merged trunk changes into the branch
diff --git a/mavibot/img/BTree.graphml b/mavibot/img/BTree.graphml
index fb610cd..ed6d1bb 100644
--- a/mavibot/img/BTree.graphml
+++ b/mavibot/img/BTree.graphml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
-  <!--Created by yFiles for Java 2.10-->
+  <!--Created by yEd 3.12.2-->
   <key for="graphml" id="d0" yfiles.type="resources"/>
   <key for="port" id="d1" yfiles.type="portgraphics"/>
   <key for="port" id="d2" yfiles.type="portgeometry"/>
@@ -38,7 +38,7 @@
           <y:Geometry height="31.26399999999998" width="55.60435455999997" x="-302.008" y="97.3560000000002"/>
           <y:Fill color="#CCFFFF" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.802177279999984" y="13.63199999999999">
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.802177279999967" y="13.63199999999999">
             <y:LabelModel>
               <y:SmartNodeLabelModel distance="4.0"/>
             </y:LabelModel>
@@ -53,10 +53,10 @@
     <node id="n2">
       <data key="d6">
         <y:ShapeNode>
-          <y:Geometry height="20.0" width="110.69599999999997" x="-412.7679999999999" y="-49.75199999999998"/>
+          <y:Geometry height="20.0" width="110.69599999999997" x="-232.89782271999988" y="-7.503999999999962"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="91.861328125" x="9.417335937499985" y="0.93359375">BTree header 1<y:LabelModel>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="91.861328125" x="9.417335937499956" y="0.93359375">BTree header 1<y:LabelModel>
               <y:SmartNodeLabelModel distance="4.0"/>
             </y:LabelModel>
             <y:ModelParameter>
@@ -73,7 +73,7 @@
           <y:Geometry height="31.26399999999998" width="6.4523545600000105" x="-302.008" y="97.3560000000002"/>
           <y:Fill color="#FFCC99" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="6" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="8.4326171875" x="-0.9901313137499947" y="-0.5008125000000234">N
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="6" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="8.4326171875" x="-0.9901313137499983" y="-0.5008125000000234">N
 E
 X
 T<y:LabelModel>
@@ -93,7 +93,7 @@
           <y:Geometry height="31.26399999999998" width="55.60435455999997" x="-59.54399999999973" y="96.84400000000018"/>
           <y:Fill color="#00CCFF" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.802177279999995" y="13.63199999999999">
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.80217727999998" y="13.63199999999999">
             <y:LabelModel>
               <y:SmartNodeLabelModel distance="4.0"/>
             </y:LabelModel>
@@ -149,7 +149,7 @@
           <y:Geometry height="31.26399999999998" width="55.60435455999997" x="-241.39199999999994" y="97.3560000000002"/>
           <y:Fill color="#CCFFFF" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.80217727999998" y="13.63199999999999">
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.802177279999995" y="13.63199999999999">
             <y:LabelModel>
               <y:SmartNodeLabelModel distance="4.0"/>
             </y:LabelModel>
@@ -187,7 +187,7 @@
           <y:Geometry height="31.26399999999998" width="55.60435455999997" x="1.072000000000287" y="96.84400000000018"/>
           <y:Fill color="#00CCFF" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.802177279999995" y="13.63199999999999">
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.802177279999984" y="13.63199999999999">
             <y:LabelModel>
               <y:SmartNodeLabelModel distance="4.0"/>
             </y:LabelModel>
@@ -205,7 +205,7 @@
           <y:Geometry height="31.26399999999998" width="6.4523545600000105" x="1.072000000000287" y="96.84400000000018"/>
           <y:Fill color="#FFCC99" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="6" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="8.4326171875" x="-0.9901313137499983" y="-0.5008125000000092">N
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="6" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="8.4326171875" x="-0.9901313137499947" y="-0.5008125000000092">N
 E
 X
 T<y:LabelModel>
@@ -225,7 +225,7 @@
           <y:Geometry height="31.26399999999998" width="55.60435455999997" x="182.9200000000004" y="96.84400000000018"/>
           <y:Fill color="#3366FF" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.802177279999967" y="13.63199999999999">
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.802177279999995" y="13.63199999999999">
             <y:LabelModel>
               <y:SmartNodeLabelModel distance="4.0"/>
             </y:LabelModel>
@@ -243,7 +243,7 @@
           <y:Geometry height="31.26399999999998" width="55.60435455999997" x="61.68800000000033" y="96.8440000000002"/>
           <y:Fill color="#00CCFF" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.802177279999967" y="13.63199999999999">
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="25.80217727999998" y="13.63199999999999">
             <y:LabelModel>
               <y:SmartNodeLabelModel distance="4.0"/>
             </y:LabelModel>
@@ -261,7 +261,7 @@
           <y:Geometry height="31.26399999999998" width="6.4523545600000105" x="-295.55564544" y="97.3560000000002"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="6" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="7.626953125" x="-0.5872992824999947" y="-0.5008125000000234">S
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="6" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="7.626953125" x="-0.5872992824999983" y="-0.5008125000000234">S
 I
 Z
 E<y:LabelModel>
@@ -381,7 +381,7 @@
           <y:Geometry height="5.424000000000007" width="5.424000000000007" x="-180.26182271999988" y="65.49600000000007"/>
           <y:Fill hasColor="false" transparent="false"/>
           <y:BorderStyle hasColor="false" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="0.7120000000000033" y="0.7120000000000033">
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="0.7119999999999891" y="0.7120000000000033">
             <y:LabelModel>
               <y:SmartNodeLabelModel distance="4.0"/>
             </y:LabelModel>
@@ -432,10 +432,10 @@
     <node id="n22">
       <data key="d6">
         <y:ShapeNode>
-          <y:Geometry height="20.0" width="110.69599999999997" x="-412.7679999999999" y="-24.503999999999962"/>
+          <y:Geometry height="20.0" width="110.69599999999997" x="1.072000000000287" y="-7.503999999999962"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="91.861328125" x="9.417335937499985" y="0.93359375">BTree header 2<y:LabelModel>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="91.861328125" x="9.417335937499956" y="0.93359375">BTree header 2<y:LabelModel>
               <y:SmartNodeLabelModel distance="4.0"/>
             </y:LabelModel>
             <y:ModelParameter>
@@ -449,10 +449,10 @@
     <node id="n23">
       <data key="d6">
         <y:ShapeNode>
-          <y:Geometry height="20.0" width="110.69599999999997" x="-412.7679999999999" y="0.7440000000000566"/>
+          <y:Geometry height="20.0" width="110.69599999999997" x="188.44435456000048" y="-7.503999999999962"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#000000" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="91.861328125" x="9.417335937499985" y="0.9335937499999716">BTree header 3<y:LabelModel>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="91.861328125" x="9.417335937499956" y="0.93359375">BTree header 3<y:LabelModel>
               <y:SmartNodeLabelModel distance="4.0"/>
             </y:LabelModel>
             <y:ModelParameter>
@@ -634,10 +634,18 @@
       <data key="d10">
         <y:PolyLineEdge>
           <y:Path sx="-55.347999999999985" sy="0.0" tx="0.0" ty="0.0">
-            <y:Point x="-274.20582272" y="-39.75199999999998"/>
+            <y:Point x="-274.20582272" y="2.4960000000000377"/>
           </y:Path>
           <y:LineStyle color="#FF0000" type="line" width="2.0"/>
           <y:Arrows source="none" target="standard"/>
+          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="26.69921875" x="-54.61727596707033" y="8.362964129197486">info<y:LabelModel>
+              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.21572713406743133" segment="-1"/>
+            </y:ModelParameter>
+            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
+          </y:EdgeLabel>
           <y:BendStyle smoothed="false"/>
         </y:PolyLineEdge>
       </data>
@@ -646,10 +654,18 @@
       <data key="d10">
         <y:PolyLineEdge>
           <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
-            <y:Point x="-31.741822719999732" y="-14.503999999999962"/>
+            <y:Point x="-31.741822719999732" y="2.4960000000000377"/>
           </y:Path>
           <y:LineStyle color="#FF0000" type="line" width="2.0"/>
           <y:Arrows source="none" target="standard"/>
+          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="26.69921875" x="-46.16343212170262" y="7.079135975280693">info<y:LabelModel>
+              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.2011113821065497" segment="-1"/>
+            </y:ModelParameter>
+            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
+          </y:EdgeLabel>
           <y:BendStyle smoothed="false"/>
         </y:PolyLineEdge>
       </data>
@@ -657,52 +673,53 @@
     <edge id="e9" source="n23" target="n11">
       <data key="d10">
         <y:PolyLineEdge>
-          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
-            <y:Point x="210.7221772800004" y="10.744000000000057"/>
-          </y:Path>
+          <y:Path sx="-33.07017728000005" sy="-9.988187500000038" tx="0.0" ty="0.0"/>
           <y:LineStyle color="#FF0000" type="line" width="2.0"/>
           <y:Arrows source="none" target="standard"/>
+          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="26.69921875" x="-13.349615322538682" y="4.983726211547889">info<y:LabelModel>
+              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/>
+            </y:ModelParameter>
+            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
+          </y:EdgeLabel>
           <y:BendStyle smoothed="false"/>
         </y:PolyLineEdge>
       </data>
     </edge>
-    <edge id="e10" source="n1" target="n24">
+    <edge id="e10" source="n2" target="n24">
       <data key="d9"/>
       <data key="d10">
         <y:PolyLineEdge>
           <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
-            <y:Point x="-274.20582272" y="162.0"/>
-            <y:Point x="-92.35782271999983" y="162.0"/>
+            <y:Point x="-92.35782271999983" y="2.4960000000000377"/>
           </y:Path>
-          <y:LineStyle color="#999999" type="line" width="3.0"/>
+          <y:LineStyle color="#FF0000" type="line" width="1.0"/>
           <y:Arrows source="none" target="standard"/>
           <y:BendStyle smoothed="false"/>
         </y:PolyLineEdge>
       </data>
     </edge>
-    <edge id="e11" source="n4" target="n25">
+    <edge id="e11" source="n22" target="n25">
       <data key="d9"/>
       <data key="d10">
         <y:PolyLineEdge>
           <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
-            <y:Point x="-31.741822719999746" y="163.0"/>
-            <y:Point x="150.10617728000037" y="163.0"/>
+            <y:Point x="150.10617728000034" y="2.4960000000000377"/>
           </y:Path>
-          <y:LineStyle color="#999999" type="line" width="3.0"/>
+          <y:LineStyle color="#FF0000" type="line" width="1.0"/>
           <y:Arrows source="none" target="standard"/>
           <y:BendStyle smoothed="false"/>
         </y:PolyLineEdge>
       </data>
     </edge>
-    <edge id="e12" source="n11" target="n26">
+    <edge id="e12" source="n23" target="n26">
       <data key="d9"/>
       <data key="d10">
         <y:PolyLineEdge>
-          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
-            <y:Point x="210.7221772800004" y="163.5031185031185"/>
-            <y:Point x="271.3381772800004" y="163.5031185031185"/>
-          </y:Path>
-          <y:LineStyle color="#999999" type="line" width="3.0"/>
+          <y:Path sx="27.54582271999996" sy="10.011812499999962" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FF0000" type="line" width="1.0"/>
           <y:Arrows source="none" target="standard"/>
           <y:BendStyle smoothed="false"/>
         </y:PolyLineEdge>
diff --git a/mavibot/img/BTree.png b/mavibot/img/BTree.png
index 5dcb295..783abb5 100644
--- a/mavibot/img/BTree.png
+++ b/mavibot/img/BTree.png
Binary files differ
diff --git a/mavibot/img/RMHeader.graphml b/mavibot/img/RMHeader.graphml
index 517ff48..784ac8e 100644
--- a/mavibot/img/RMHeader.graphml
+++ b/mavibot/img/RMHeader.graphml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
-  <!--Created by yFiles for Java 2.10-->
+  <!--Created by yEd 3.12.2-->
   <key for="graphml" id="d0" yfiles.type="resources"/>
   <key for="port" id="d1" yfiles.type="portgraphics"/>
   <key for="port" id="d2" yfiles.type="portgeometry"/>
@@ -17,10 +17,10 @@
     <node id="n0">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="152.0" width="229.0" x="648.5" y="248.0"/>
+          <y:Geometry height="263.0" width="229.0" x="648.5" y="248.0"/>
           <y:Fill color="#FFCC99" transparent="false"/>
           <y:BorderStyle hasColor="false" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="139.4453125" x="-143.4453125" y="4.0">RecordManager Header</y:NodeLabel>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="139.4453125" x="44.77734375" y="-28.06640625">RecordManager Header</y:NodeLabel>
         </y:GenericNode>
       </data>
     </node>
@@ -426,7 +426,424 @@
           <y:Geometry height="30.0" width="216.0" x="654.5" y="362.0"/>
           <y:Fill hasColor="false" transparent="false"/>
           <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="79.7734375" x="4.0" y="5.93359375">LastFreePage</y:NodeLabel>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="187.99609375" x="4.0" y="5.93359375">Current B-tree of B-trees offset</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n29">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="654.5" y="398.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n30">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="681.5" y="398.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n31">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="708.5" y="398.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n32">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="735.5" y="398.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n33">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="762.5" y="398.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n34">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="789.5" y="398.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n35">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="816.5" y="398.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n36">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="843.5" y="398.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n37">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="654.5" y="435.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n38">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="681.5" y="435.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n39">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="708.5" y="435.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n40">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="735.5" y="435.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n41">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="762.5" y="435.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n42">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="789.5" y="435.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n43">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="816.5" y="435.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n44">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="843.5" y="435.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n45">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="654.5" y="471.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n46">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="681.5" y="471.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n47">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="708.5" y="471.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n48">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="735.5" y="471.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n49">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="762.5" y="471.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n50">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="789.5" y="471.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n51">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="816.5" y="471.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n52">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="843.5" y="471.5"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n53">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="655.0" y="398.5"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="192.6484375" x="4.0" y="5.93359375">Previous B-tree of B-trees offset</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n54">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="655.0" y="435.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="207.958984375" x="4.0" y="5.93359375">Current Copied Pages B-tree offset</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n55">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="654.5" y="471.5"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="207.958984375" x="4.0" y="5.93359375">Current Copied Pages B-tree offset</y:NodeLabel>
         </y:GenericNode>
       </data>
     </node>
diff --git a/mavibot/img/RMHeader.png b/mavibot/img/RMHeader.png
index 145e1c2..937969d 100644
--- a/mavibot/img/RMHeader.png
+++ b/mavibot/img/RMHeader.png
Binary files differ
diff --git a/mavibot/img/btreeHeader.graphml b/mavibot/img/btreeHeader.graphml
index 999c2eb..3bcdca6 100644
--- a/mavibot/img/btreeHeader.graphml
+++ b/mavibot/img/btreeHeader.graphml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
-  <!--Created by yFiles for Java 2.10-->
+  <!--Created by yFiles for Java 2.11-->
   <key for="graphml" id="d0" yfiles.type="resources"/>
   <key for="port" id="d1" yfiles.type="portgraphics"/>
   <key for="port" id="d2" yfiles.type="portgeometry"/>
@@ -17,10 +17,10 @@
     <node id="n0">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="346.0256" width="229.0" x="93.0" y="24.0"/>
+          <y:Geometry height="157.0256" width="229.0" x="93.0" y="24.0"/>
           <y:Fill color="#FFCC99" transparent="false"/>
           <y:BorderStyle hasColor="false" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="81.84765625" x="-85.84765625" y="4.0">BTree Header</y:NodeLabel>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="81.84765625" x="73.576171875" y="-22.1328125">BTree Header</y:NodeLabel>
         </y:GenericNode>
       </data>
     </node>
@@ -444,34 +444,27 @@
     <node id="n28">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="99.0" y="181.0"/>
-          <y:Fill color="#FFFF99" transparent="false"/>
-          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="11.5" y="13.0"/>
+          <y:Geometry height="199.0256" width="229.0" x="93.0" y="211.0256"/>
+          <y:Fill color="#FFCC99" transparent="false"/>
+          <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="59.458984375" x="73.576171875" y="-22.1328125">BTreeInfo</y:NodeLabel>
         </y:GenericNode>
       </data>
     </node>
     <node id="n29">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="126.0" y="181.0"/>
+          <y:Geometry height="30.0" width="27.0" x="99.0" y="220.0384"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
-<y:LabelModel>
-              <y:SmartNodeLabelModel distance="4.0"/>
-            </y:LabelModel>
-            <y:ModelParameter>
-              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
-            </y:ModelParameter>
-          </y:NodeLabel>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="11.5" y="13.0"/>
         </y:GenericNode>
       </data>
     </node>
     <node id="n30">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="153.0" y="181.0"/>
+          <y:Geometry height="30.0" width="27.0" x="126.0" y="220.0384"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
           <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
@@ -488,37 +481,7 @@
     <node id="n31">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="180.0" y="181.0"/>
-          <y:Fill color="#FFFF99" transparent="false"/>
-          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-78.4619140625" y="5.93359375"/>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n32">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNode">
-          <y:Geometry height="30.0" width="108.0" x="99.0" y="181.0"/>
-          <y:Fill hasColor="false" transparent="false"/>
-          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="87.6953125" x="4.0" y="5.93359375">BTreePageSize</y:NodeLabel>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n33">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="99.0" y="219.0"/>
-          <y:Fill color="#FFFF99" transparent="false"/>
-          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="11.5" y="13.0"/>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n34">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="126.0" y="219.0"/>
+          <y:Geometry height="30.0" width="27.0" x="153.0" y="220.0384"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
           <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
@@ -532,10 +495,40 @@
         </y:GenericNode>
       </data>
     </node>
+    <node id="n32">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="180.0" y="220.0384"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-78.4619140625" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n33">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="108.0" x="99.0" y="220.0384"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="87.6953125" x="4.0" y="5.93359375">BTreePageSize</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n34">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="99.0" y="258.0384"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="11.5" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
     <node id="n35">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="153.0" y="219.0"/>
+          <y:Geometry height="30.0" width="27.0" x="126.0" y="258.0384"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
           <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
@@ -552,70 +545,7 @@
     <node id="n36">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="180.0" y="219.0"/>
-          <y:Fill color="#FFFF99" transparent="false"/>
-          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-78.4619140625" y="5.93359375"/>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n37">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNode">
-          <y:Geometry height="30.0" width="108.0" x="99.0" y="219.0"/>
-          <y:Fill hasColor="false" transparent="false"/>
-          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="72.53125" x="4.0" y="5.93359375">BTree name</y:NodeLabel>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n38">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="70.0" x="210.0" y="219.0"/>
-          <y:Fill color="#FFFF99" transparent="false"/>
-          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="31.1015625" y="5.93359375">
-<y:LabelModel>
-              <y:SmartNodeLabelModel distance="4.0"/>
-            </y:LabelModel>
-            <y:ModelParameter>
-              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
-            </y:ModelParameter>
-          </y:NodeLabel>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n39">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNode">
-          <y:Geometry height="30.0" width="70.0" x="210.0" y="219.0"/>
-          <y:Fill hasColor="false" transparent="false"/>
-          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="35.8984375" x="17.05078125" y="5.93359375">xyz...<y:LabelModel>
-              <y:SmartNodeLabelModel distance="4.0"/>
-            </y:LabelModel>
-            <y:ModelParameter>
-              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
-            </y:ModelParameter>
-          </y:NodeLabel>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n40">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="99.0" y="257.0"/>
-          <y:Fill color="#FFFF99" transparent="false"/>
-          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="11.5" y="13.0"/>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n41">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="126.0" y="257.0"/>
+          <y:Geometry height="30.0" width="27.0" x="153.0" y="258.0384"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
           <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
@@ -629,10 +559,73 @@
         </y:GenericNode>
       </data>
     </node>
+    <node id="n37">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="180.0" y="258.0384"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-78.4619140625" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n38">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="108.0" x="99.0" y="258.0384"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="72.53125" x="4.0" y="5.93359375">BTree name</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n39">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="70.0" x="210.0" y="258.0384"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="31.1015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n40">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="70.0" x="210.0" y="258.0384"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="35.8984375" x="17.05078125" y="5.93359375">xyz...<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n41">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="99.0" y="296.03839999999997"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="11.5" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
     <node id="n42">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="153.0" y="257.0"/>
+          <y:Geometry height="30.0" width="27.0" x="126.0" y="296.03839999999997"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
           <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
@@ -649,70 +642,7 @@
     <node id="n43">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="180.0" y="257.0"/>
-          <y:Fill color="#FFFF99" transparent="false"/>
-          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-78.4619140625" y="5.93359375"/>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n44">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNode">
-          <y:Geometry height="30.0" width="108.0" x="99.0" y="257.0"/>
-          <y:Fill hasColor="false" transparent="false"/>
-          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="78.35546875" x="4.0" y="5.93359375">KeySerializer</y:NodeLabel>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n45">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="70.0" x="210.0" y="257.0"/>
-          <y:Fill color="#FFFF99" transparent="false"/>
-          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="31.1015625" y="5.93359375">
-<y:LabelModel>
-              <y:SmartNodeLabelModel distance="4.0"/>
-            </y:LabelModel>
-            <y:ModelParameter>
-              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
-            </y:ModelParameter>
-          </y:NodeLabel>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n46">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNode">
-          <y:Geometry height="30.0" width="70.0" x="210.0" y="257.0"/>
-          <y:Fill hasColor="false" transparent="false"/>
-          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="35.8984375" x="17.05078125" y="5.93359375">xyz...<y:LabelModel>
-              <y:SmartNodeLabelModel distance="4.0"/>
-            </y:LabelModel>
-            <y:ModelParameter>
-              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
-            </y:ModelParameter>
-          </y:NodeLabel>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n47">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="99.0" y="295.0"/>
-          <y:Fill color="#FFFF99" transparent="false"/>
-          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="11.5" y="13.0"/>
-        </y:GenericNode>
-      </data>
-    </node>
-    <node id="n48">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="126.0" y="295.0"/>
+          <y:Geometry height="30.0" width="27.0" x="153.0" y="296.03839999999997"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
           <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
@@ -726,10 +656,73 @@
         </y:GenericNode>
       </data>
     </node>
+    <node id="n44">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="180.0" y="296.03839999999997"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-78.4619140625" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n45">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="108.0" x="99.0" y="296.03839999999997"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="78.35546875" x="4.0" y="5.93359375">KeySerializer</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n46">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="70.0" x="210.0" y="296.03839999999997"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="31.1015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n47">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="70.0" x="210.0" y="296.03839999999997"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="35.8984375" x="17.05078125" y="5.93359375">xyz...<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n48">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="99.0" y="334.0383999999999"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="11.5" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
     <node id="n49">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="153.0" y="295.0"/>
+          <y:Geometry height="30.0" width="27.0" x="126.0" y="334.0383999999999"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
           <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
@@ -746,27 +739,44 @@
     <node id="n50">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="180.0" y="295.0"/>
+          <y:Geometry height="30.0" width="27.0" x="153.0" y="334.0383999999999"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n51">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="180.0" y="334.0383999999999"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
           <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-78.4619140625" y="5.93359375"/>
         </y:GenericNode>
       </data>
     </node>
-    <node id="n51">
+    <node id="n52">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNode">
-          <y:Geometry height="30.0" width="108.0" x="99.0" y="295.0"/>
+          <y:Geometry height="30.0" width="108.0" x="99.0" y="334.0383999999999"/>
           <y:Fill hasColor="false" transparent="false"/>
           <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
           <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="89.640625" x="4.0" y="5.93359375">ValueSerializer</y:NodeLabel>
         </y:GenericNode>
       </data>
     </node>
-    <node id="n52">
+    <node id="n53">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="70.0" x="210.0" y="295.0"/>
+          <y:Geometry height="30.0" width="70.0" x="210.0" y="334.0383999999999"/>
           <y:Fill color="#FFFF99" transparent="false"/>
           <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
           <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="31.1015625" y="5.93359375">
@@ -780,10 +790,10 @@
         </y:GenericNode>
       </data>
     </node>
-    <node id="n53">
+    <node id="n54">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNode">
-          <y:Geometry height="30.0" width="70.0" x="210.0" y="295.0"/>
+          <y:Geometry height="30.0" width="70.0" x="210.0" y="334.0383999999999"/>
           <y:Fill hasColor="false" transparent="false"/>
           <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
           <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="35.8984375" x="17.05078125" y="5.93359375">xyz...<y:LabelModel>
@@ -796,7 +806,27 @@
         </y:GenericNode>
       </data>
     </node>
-    <node id="n54">
+    <node id="n55">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="99.0" y="372.0383999999999"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="11.5" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n56">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="27.0" x="99.0" y="372.0383999999999"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="78.7421875" x="4.0" y="5.93359375">dupsAllowed</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n57">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
           <y:Geometry height="30.0" width="27.0" x="99.0" y="143.0"/>
@@ -813,7 +843,7 @@
         </y:GenericNode>
       </data>
     </node>
-    <node id="n55">
+    <node id="n58">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
           <y:Geometry height="30.0" width="27.0" x="126.0" y="143.0"/>
@@ -830,7 +860,7 @@
         </y:GenericNode>
       </data>
     </node>
-    <node id="n56">
+    <node id="n59">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
           <y:Geometry height="30.0" width="27.0" x="153.0" y="143.0"/>
@@ -847,7 +877,7 @@
         </y:GenericNode>
       </data>
     </node>
-    <node id="n57">
+    <node id="n60">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
           <y:Geometry height="30.0" width="27.0" x="180.0" y="143.0"/>
@@ -864,7 +894,7 @@
         </y:GenericNode>
       </data>
     </node>
-    <node id="n58">
+    <node id="n61">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
           <y:Geometry height="30.0" width="27.0" x="207.0" y="143.0"/>
@@ -881,7 +911,7 @@
         </y:GenericNode>
       </data>
     </node>
-    <node id="n59">
+    <node id="n62">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
           <y:Geometry height="30.0" width="27.0" x="234.0" y="143.0"/>
@@ -898,7 +928,7 @@
         </y:GenericNode>
       </data>
     </node>
-    <node id="n60">
+    <node id="n63">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
           <y:Geometry height="30.0" width="27.0" x="261.0" y="143.0"/>
@@ -915,7 +945,7 @@
         </y:GenericNode>
       </data>
     </node>
-    <node id="n61">
+    <node id="n64">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNodeWithShadow">
           <y:Geometry height="30.0" width="27.0" x="288.0" y="143.0"/>
@@ -925,36 +955,30 @@
         </y:GenericNode>
       </data>
     </node>
-    <node id="n62">
+    <node id="n65">
       <data key="d6">
         <y:GenericNode configuration="ShinyPlateNode">
           <y:Geometry height="30.0" width="216.0" x="99.0" y="143.0"/>
           <y:Fill hasColor="false" transparent="false"/>
           <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="102.349609375" x="4.0" y="5.93359375">NextBtreeHeader</y:NodeLabel>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="94.896484375" x="4.0" y="5.93359375">BTreeInfoOffset</y:NodeLabel>
         </y:GenericNode>
       </data>
     </node>
-    <node id="n63">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
-          <y:Geometry height="30.0" width="27.0" x="99.0" y="333.0"/>
-          <y:Fill color="#FFFF99" transparent="false"/>
-          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="11.5" y="13.0"/>
-        </y:GenericNode>
+    <edge id="e0" source="n65" target="n28">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="373.0" y="158.0"/>
+            <y:Point x="373.0" y="310.5384"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
       </data>
-    </node>
-    <node id="n64">
-      <data key="d6">
-        <y:GenericNode configuration="ShinyPlateNode">
-          <y:Geometry height="30.0" width="27.0" x="99.0" y="333.0"/>
-          <y:Fill hasColor="false" transparent="false"/>
-          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
-          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="78.7421875" x="4.0" y="5.93359375">dupsAllowed</y:NodeLabel>
-        </y:GenericNode>
-      </data>
-    </node>
+    </edge>
   </graph>
   <data key="d0">
     <y:Resources/>
diff --git a/mavibot/img/btreeHeader.png b/mavibot/img/btreeHeader.png
index cff1f78..2bc53ae 100644
--- a/mavibot/img/btreeHeader.png
+++ b/mavibot/img/btreeHeader.png
Binary files differ
diff --git a/mavibot/img/leaves.graphml b/mavibot/img/leaves.graphml
new file mode 100644
index 0000000..dbc796a
--- /dev/null
+++ b/mavibot/img/leaves.graphml
@@ -0,0 +1,1173 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
+  <!--Created by yEd 3.12.2-->
+  <key for="graphml" id="d0" yfiles.type="resources"/>
+  <key for="port" id="d1" yfiles.type="portgraphics"/>
+  <key for="port" id="d2" yfiles.type="portgeometry"/>
+  <key for="port" id="d3" yfiles.type="portuserdata"/>
+  <key attr.name="url" attr.type="string" for="node" id="d4"/>
+  <key attr.name="description" attr.type="string" for="node" id="d5"/>
+  <key for="node" id="d6" yfiles.type="nodegraphics"/>
+  <key attr.name="Description" attr.type="string" for="graph" id="d7"/>
+  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
+  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
+  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
+  <graph edgedefault="directed" id="G">
+    <data key="d7"/>
+    <node id="n0">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="71.0" width="229.0" x="342.5" y="260.0"/>
+          <y:Fill color="#FFCC99" transparent="false"/>
+          <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="178.7734375" x="25.11328125" y="-29.06640625">Leaf with N/2 keys and values</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n1">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="349.0" y="266.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n2">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="376.0" y="266.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n3">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="403.0" y="266.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n4">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="430.0" y="266.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n5">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="457.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n6">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="484.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n7">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="511.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n8">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="538.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n9">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="349.0" y="266.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="4.0" x="4.0" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n10">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="71.0" width="229.0" x="342.5" y="374.0"/>
+          <y:Fill color="#FFCC99" transparent="false"/>
+          <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="164.892578125" x="32.0537109375" y="-29.06640625">Leaf with N keys and values</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n11">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="349.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n12">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="376.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n13">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="403.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n14">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="430.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n15">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="457.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n16">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="484.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n17">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="511.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n18">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="538.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n19">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="349.0" y="380.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="4.0" x="4.0" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n20">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="71.0" width="229.0" x="611.5" y="260.0"/>
+          <y:Fill color="#FFCC99" transparent="false"/>
+          <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="195.912109375" x="16.5439453125" y="-29.06640625">Root Leaf with one key and value</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n21">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="618.0" y="266.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n22">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="645.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n23">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="672.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n24">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="699.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n25">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="726.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n26">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="753.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n27">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="780.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n28">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="807.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n29">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="618.0" y="266.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="4.0" x="4.0" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n30">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="349.0" y="296.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n31">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="376.0" y="296.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n32">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="403.0" y="296.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n33">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="430.0" y="296.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n34">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="457.0" y="296.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n35">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="484.0" y="296.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n36">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="511.0" y="296.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n37">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="538.0" y="296.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n38">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="349.0" y="296.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="4.0" x="4.0" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n39">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="349.0" y="410.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n40">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="376.0" y="410.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n41">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="403.0" y="410.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n42">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="430.0" y="410.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n43">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="457.0" y="410.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n44">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="484.0" y="410.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n45">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="511.0" y="410.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n46">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="538.0" y="410.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n47">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="349.0" y="410.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="4.0" x="4.0" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n48">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="618.0" y="296.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n49">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="645.0" y="296.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n50">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="672.0" y="296.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n51">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="699.0" y="296.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n52">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="726.0" y="296.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n53">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="753.0" y="296.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n54">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="780.0" y="296.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n55">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="807.0" y="296.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n56">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="618.0" y="296.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="4.0" x="4.0" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n57">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="71.0" width="229.0" x="611.5" y="374.0"/>
+          <y:Fill color="#FFCC99" transparent="false"/>
+          <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="179.880859375" x="16.5439453125" y="-29.06640625">Root Leaf with no key or value</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n58">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="618.0" y="380.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n59">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="645.0" y="380.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n60">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="672.0" y="380.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n61">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="699.0" y="380.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n62">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="726.0" y="380.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n63">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="753.0" y="380.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n64">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="780.0" y="380.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n65">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="807.0" y="380.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n66">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="618.0" y="380.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="4.0" x="4.0" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n67">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="618.0" y="410.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n68">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="645.0" y="410.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n69">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="672.0" y="410.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n70">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="699.0" y="410.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n71">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="726.0" y="410.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n72">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="753.0" y="410.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n73">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="780.0" y="410.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n74">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="807.0" y="410.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n75">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="618.0" y="410.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="4.0" x="4.0" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+  </graph>
+  <data key="d0">
+    <y:Resources/>
+  </data>
+</graphml>
diff --git a/mavibot/img/leaves.png b/mavibot/img/leaves.png
new file mode 100644
index 0000000..86a72bd
--- /dev/null
+++ b/mavibot/img/leaves.png
Binary files differ
diff --git a/mavibot/img/nodes.graphml b/mavibot/img/nodes.graphml
new file mode 100644
index 0000000..0ef2aa0
--- /dev/null
+++ b/mavibot/img/nodes.graphml
@@ -0,0 +1,468 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
+  <!--Created by yEd 3.12.2-->
+  <key for="graphml" id="d0" yfiles.type="resources"/>
+  <key for="port" id="d1" yfiles.type="portgraphics"/>
+  <key for="port" id="d2" yfiles.type="portgeometry"/>
+  <key for="port" id="d3" yfiles.type="portuserdata"/>
+  <key attr.name="url" attr.type="string" for="node" id="d4"/>
+  <key attr.name="description" attr.type="string" for="node" id="d5"/>
+  <key for="node" id="d6" yfiles.type="nodegraphics"/>
+  <key attr.name="Description" attr.type="string" for="graph" id="d7"/>
+  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
+  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
+  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
+  <graph edgedefault="directed" id="G">
+    <data key="d7"/>
+    <node id="n0">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="42.0" width="229.0" x="342.5" y="260.0"/>
+          <y:Fill color="#FFCC99" transparent="false"/>
+          <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="123.14453125" x="52.927734375" y="-29.06640625">Node with N/2 keys </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n1">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="349.0" y="266.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n2">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="376.0" y="266.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n3">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="403.0" y="266.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n4">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="430.0" y="266.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n5">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="457.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n6">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="484.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n7">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="511.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n8">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="538.0" y="266.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n9">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="349.0" y="266.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="4.0" x="4.0" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n10">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="42.0" width="229.0" x="342.5" y="374.0"/>
+          <y:Fill color="#FFCC99" transparent="false"/>
+          <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="105.466796875" x="61.7666015625" y="-29.06640625">Node with N keys</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n11">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="349.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n12">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="376.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n13">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="403.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n14">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="430.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n15">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="457.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n16">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="484.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n17">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="511.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n18">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="538.0" y="380.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n19">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="349.0" y="380.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="4.0" x="4.0" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n20">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="42.0" width="229.0" x="342.5" y="488.0"/>
+          <y:Fill color="#FFCC99" transparent="false"/>
+          <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="142.603515625" x="43.1982421875" y="-29.06640625">Root Node with one key</y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n21">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="349.0" y="494.0"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n22">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="376.0" y="494.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n23">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="403.0" y="494.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n24">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="430.0" y="494.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n25">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="457.0" y="494.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n26">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="484.0" y="494.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n27">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="511.0" y="494.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="7.796875" x="9.6015625" y="5.93359375">
+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n28">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="27.0" x="538.0" y="494.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="free" modelPosition="anywhere" textColor="#000000" visible="true" width="4.0" x="-184.7802734375" y="5.93359375"/>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n29">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNode">
+          <y:Geometry height="30.0" width="216.0" x="349.0" y="494.0"/>
+          <y:Fill hasColor="false" transparent="false"/>
+          <y:BorderStyle color="#0000FF" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="l" textColor="#000000" visible="true" width="4.0" x="4.0" y="13.0"/>
+        </y:GenericNode>
+      </data>
+    </node>
+  </graph>
+  <data key="d0">
+    <y:Resources/>
+  </data>
+</graphml>
diff --git a/mavibot/img/nodes.png b/mavibot/img/nodes.png
new file mode 100644
index 0000000..19dbb7d
--- /dev/null
+++ b/mavibot/img/nodes.png
Binary files differ
diff --git a/mavibot/img/trans1.graphml b/mavibot/img/trans1.graphml
new file mode 100644
index 0000000..e1e400f
--- /dev/null
+++ b/mavibot/img/trans1.graphml
@@ -0,0 +1,236 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
+  <!--Created by yEd 3.12.2-->
+  <key for="graphml" id="d0" yfiles.type="resources"/>
+  <key for="port" id="d1" yfiles.type="portgraphics"/>
+  <key for="port" id="d2" yfiles.type="portgeometry"/>
+  <key for="port" id="d3" yfiles.type="portuserdata"/>
+  <key attr.name="url" attr.type="string" for="node" id="d4"/>
+  <key attr.name="description" attr.type="string" for="node" id="d5"/>
+  <key for="node" id="d6" yfiles.type="nodegraphics"/>
+  <key attr.name="Description" attr.type="string" for="graph" id="d7"/>
+  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
+  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
+  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
+  <graph edgedefault="directed" id="G">
+    <data key="d7"/>
+    <node id="n0">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="229.08480000000054" y="262.0799999999999"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="25.7265625" x="27.13671875" y="0.078125">r 7<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n1">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="229.08480000000054" y="232.07999999999993"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="68.921875" x="5.5390625" y="3.578125">B-tree A<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n2">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="229.08480000000054" y="330.15999999999985"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 14<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n3">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="229.08480000000054" y="300.15999999999985"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="67.0859375" x="6.45703125" y="3.578125">B-tree B<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n4">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="229.08480000000054" y="398.2399999999998"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="25.7265625" x="27.13671875" y="0.078125">r 3<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n5">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="229.08480000000054" y="368.2399999999998"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="68.953125" x="5.5234375" y="3.578125">B-tree C<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n6">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="229.08480000000054" y="142.15999999999985"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 25<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n7">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="229.08480000000054" y="112.15999999999985"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="34.8359375" x="22.58203125" y="3.578125">BOB<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n8">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="119.0" x="355.1696000000011" y="12.319999999999709"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="82.9375" x="18.03125" y="3.578125">RMHeader<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n9">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="119.0" x="355.1696000000011" y="42.31999999999971"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="90.8828125" x="14.05859375" y="0.078125">currentBOB<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <edge id="e0" source="n6" target="n1">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="182.0" y="153.65999999999985"/>
+            <y:Point x="182.0" y="247.07999999999993"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e1" source="n6" target="n3">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="162.0" y="153.65999999999985"/>
+            <y:Point x="162.0" y="315.15999999999985"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e2" source="n6" target="n5">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="140.0" y="153.65999999999985"/>
+            <y:Point x="140.0" y="383.2399999999998"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e3" source="n9" target="n6">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="414.6696000000011" y="153.65999999999985"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+  </graph>
+  <data key="d0">
+    <y:Resources/>
+  </data>
+</graphml>
diff --git a/mavibot/img/trans1.png b/mavibot/img/trans1.png
new file mode 100644
index 0000000..e1a581d
--- /dev/null
+++ b/mavibot/img/trans1.png
Binary files differ
diff --git a/mavibot/img/trans2.graphml b/mavibot/img/trans2.graphml
new file mode 100644
index 0000000..0ac569e
--- /dev/null
+++ b/mavibot/img/trans2.graphml
@@ -0,0 +1,407 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
+  <!--Created by yEd 3.12.2-->
+  <key for="graphml" id="d0" yfiles.type="resources"/>
+  <key for="port" id="d1" yfiles.type="portgraphics"/>
+  <key for="port" id="d2" yfiles.type="portgeometry"/>
+  <key for="port" id="d3" yfiles.type="portuserdata"/>
+  <key attr.name="url" attr.type="string" for="node" id="d4"/>
+  <key attr.name="description" attr.type="string" for="node" id="d5"/>
+  <key for="node" id="d6" yfiles.type="nodegraphics"/>
+  <key attr.name="Description" attr.type="string" for="graph" id="d7"/>
+  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
+  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
+  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
+  <graph edgedefault="directed" id="G">
+    <data key="d7"/>
+    <node id="n0">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="343.1696000000011" y="287.39999999999964"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="25.7265625" x="27.13671875" y="0.078125">r 7<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n1">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="343.1696000000011" y="257.39999999999964"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="68.921875" x="5.5390625" y="3.578125">B-tree A<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n2">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="343.1696000000011" y="355.47999999999956"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 14<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n3">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="343.1696000000011" y="325.47999999999956"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="67.0859375" x="6.45703125" y="3.578125">B-tree B<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n4">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="343.1696000000011" y="423.5599999999995"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="25.7265625" x="27.13671875" y="0.078125">r 3<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n5">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="343.1696000000011" y="393.5599999999995"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="68.953125" x="5.5234375" y="3.578125">B-tree C<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n6">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="343.1696000000011" y="167.47999999999956"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 25<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n7">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="343.1696000000011" y="137.47999999999956"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="34.8359375" x="22.58203125" y="3.578125">BOB<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n8">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="119.0" x="469.2544000000016" y="37.63999999999942"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="82.9375" x="18.03125" y="3.578125">RMHeader<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n9">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="119.0" x="469.2544000000016" y="67.63999999999942"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="90.8828125" x="14.05859375" y="0.078125">currentBOB<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n10">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="660.3392000000022" y="287.39999999999964"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="25.7265625" x="27.13671875" y="0.078125">r 8<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n11">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="660.3392000000022" y="257.39999999999964"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="68.921875" x="5.5390625" y="3.578125">B-tree A<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n12">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="660.3392000000022" y="355.47999999999956"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 15<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n13">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="660.3392000000022" y="325.47999999999956"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="67.0859375" x="6.45703125" y="3.578125">B-tree B<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n14">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="660.3392000000022" y="167.47999999999956"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 27<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n15">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="660.3392000000022" y="137.47999999999956"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="34.8359375" x="22.58203125" y="3.578125">BOB<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <edge id="e0" source="n6" target="n1">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="296.08480000000054" y="178.97999999999956"/>
+            <y:Point x="296.08480000000054" y="272.39999999999964"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e1" source="n6" target="n3">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="276.08480000000054" y="178.97999999999956"/>
+            <y:Point x="276.08480000000054" y="340.47999999999956"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e2" source="n6" target="n5">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="254.08480000000054" y="178.97999999999956"/>
+            <y:Point x="254.08480000000054" y="408.5599999999995"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e3" source="n9" target="n7">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="528.7544000000016" y="152.47999999999956"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e4" source="n3" target="n13">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#0000FF" type="dashed" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e5" source="n1" target="n11">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#0000FF" type="dashed" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e6" source="n6" target="n14">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#0000FF" type="dashed" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e7" source="n14" target="n11">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="795.0" y="178.97999999999956"/>
+            <y:Point x="795.0" y="272.39999999999964"/>
+          </y:Path>
+          <y:LineStyle color="#0000FF" type="line" width="3.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e8" source="n14" target="n13">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="815.0" y="178.97999999999956"/>
+            <y:Point x="815.0" y="340.47999999999956"/>
+          </y:Path>
+          <y:LineStyle color="#0000FF" type="line" width="3.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e9" source="n14" target="n5">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="836.0" y="178.97999999999956"/>
+            <y:Point x="836.0" y="408.5599999999995"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+  </graph>
+  <data key="d0">
+    <y:Resources/>
+  </data>
+</graphml>
diff --git a/mavibot/img/trans2.png b/mavibot/img/trans2.png
new file mode 100644
index 0000000..3577130
--- /dev/null
+++ b/mavibot/img/trans2.png
Binary files differ
diff --git a/mavibot/img/transko.graphml b/mavibot/img/transko.graphml
new file mode 100644
index 0000000..0b94f2c
--- /dev/null
+++ b/mavibot/img/transko.graphml
@@ -0,0 +1,332 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
+  <!--Created by yEd 3.12.2-->
+  <key for="graphml" id="d0" yfiles.type="resources"/>
+  <key for="port" id="d1" yfiles.type="portgraphics"/>
+  <key for="port" id="d2" yfiles.type="portgeometry"/>
+  <key for="port" id="d3" yfiles.type="portuserdata"/>
+  <key attr.name="url" attr.type="string" for="node" id="d4"/>
+  <key attr.name="description" attr.type="string" for="node" id="d5"/>
+  <key for="node" id="d6" yfiles.type="nodegraphics"/>
+  <key attr.name="Description" attr.type="string" for="graph" id="d7"/>
+  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
+  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
+  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
+  <graph edgedefault="directed" id="G">
+    <data key="d7"/>
+    <node id="n0">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="343.33920000000217" y="349.03999999999905"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="25.7265625" x="27.13671875" y="0.078125">r 7<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n1">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="343.33920000000217" y="319.03999999999905"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="68.921875" x="5.5390625" y="3.578125">B-tree A<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n2">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="343.33920000000217" y="417.119999999999"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 14<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n3">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="343.33920000000217" y="387.119999999999"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="67.0859375" x="6.45703125" y="3.578125">B-tree B<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n4">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="343.33920000000217" y="485.1999999999989"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="25.7265625" x="27.13671875" y="0.078125">r 3<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n5">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="343.33920000000217" y="455.1999999999989"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="68.953125" x="5.5234375" y="3.578125">B-tree C<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n6">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="343.33920000000217" y="229.11999999999898"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 25<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n7">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="343.33920000000217" y="199.11999999999898"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="34.8359375" x="22.58203125" y="3.578125">BOB<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n8">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="119.0" x="469.4240000000027" y="99.27999999999884"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="82.9375" x="18.03125" y="3.578125">RMHeader<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n9">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="119.0" x="469.4240000000027" y="129.27999999999884"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="90.8828125" x="14.05859375" y="0.078125">currentBOB<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n10">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="660.5088000000032" y="349.03999999999905"/>
+          <y:Fill color="#C0C0C0" color2="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="25.7265625" x="27.13671875" y="0.078125">r 8<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n11">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="660.5088000000032" y="319.03999999999905"/>
+          <y:Fill color="#C0C0C0" color2="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="68.921875" x="5.5390625" y="3.578125">B-tree A<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n12">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="660.5088000000032" y="417.119999999999"/>
+          <y:Fill color="#C0C0C0" color2="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 15<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n13">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="660.5088000000032" y="387.119999999999"/>
+          <y:Fill color="#C0C0C0" color2="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="67.0859375" x="6.45703125" y="3.578125">B-tree B<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n14">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="660.5088000000032" y="229.11999999999898"/>
+          <y:Fill color="#C0C0C0" color2="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 27<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n15">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="660.5088000000032" y="199.11999999999898"/>
+          <y:Fill color="#C0C0C0" color2="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="34.8359375" x="22.58203125" y="3.578125">BOB<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <edge id="e0" source="n6" target="n1">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="296.2544000000016" y="240.61999999999898"/>
+            <y:Point x="296.2544000000016" y="334.03999999999905"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e1" source="n6" target="n3">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="276.2544000000016" y="240.61999999999898"/>
+            <y:Point x="276.2544000000016" y="402.119999999999"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e2" source="n6" target="n5">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="254.25440000000162" y="240.61999999999898"/>
+            <y:Point x="254.25440000000162" y="470.1999999999989"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e3" source="n9" target="n7">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="528.9240000000027" y="214.11999999999898"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+  </graph>
+  <data key="d0">
+    <y:Resources/>
+  </data>
+</graphml>
diff --git a/mavibot/img/transko.png b/mavibot/img/transko.png
new file mode 100644
index 0000000..9bae17a
--- /dev/null
+++ b/mavibot/img/transko.png
Binary files differ
diff --git a/mavibot/img/transok.graphml b/mavibot/img/transok.graphml
new file mode 100644
index 0000000..0ab9321
--- /dev/null
+++ b/mavibot/img/transok.graphml
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
+  <!--Created by yEd 3.12.2-->
+  <key for="graphml" id="d0" yfiles.type="resources"/>
+  <key for="port" id="d1" yfiles.type="portgraphics"/>
+  <key for="port" id="d2" yfiles.type="portgeometry"/>
+  <key for="port" id="d3" yfiles.type="portuserdata"/>
+  <key attr.name="url" attr.type="string" for="node" id="d4"/>
+  <key attr.name="description" attr.type="string" for="node" id="d5"/>
+  <key for="node" id="d6" yfiles.type="nodegraphics"/>
+  <key attr.name="Description" attr.type="string" for="graph" id="d7"/>
+  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
+  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
+  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
+  <graph edgedefault="directed" id="G">
+    <data key="d7"/>
+    <node id="n0">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="294.33920000000217" y="358.03999999999905"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="25.7265625" x="27.13671875" y="0.078125">r 7<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n1">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="294.33920000000217" y="328.03999999999905"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="68.921875" x="5.5390625" y="3.578125">B-tree A<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n2">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="294.33920000000217" y="426.119999999999"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 14<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n3">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="294.33920000000217" y="396.119999999999"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="67.0859375" x="6.45703125" y="3.578125">B-tree B<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n4">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="294.33920000000217" y="494.1999999999989"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="25.7265625" x="27.13671875" y="0.078125">r 3<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n5">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="294.33920000000217" y="464.1999999999989"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="68.953125" x="5.5234375" y="3.578125">B-tree C<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n6">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="294.33920000000217" y="238.11999999999898"/>
+          <y:Fill color="#C0C0C0" color2="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 25<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n7">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="294.33920000000217" y="208.11999999999898"/>
+          <y:Fill color="#C0C0C0" color2="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="34.8359375" x="22.58203125" y="3.578125">BOB<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n8">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="119.0" x="420.4240000000027" y="108.27999999999884"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="82.9375" x="18.03125" y="3.578125">RMHeader<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n9">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="119.0" x="420.4240000000027" y="138.27999999999884"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="90.8828125" x="14.05859375" y="0.078125">currentBOB<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n10">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="611.5088000000032" y="358.03999999999905"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="25.7265625" x="27.13671875" y="0.078125">r 8<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n11">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="611.5088000000032" y="328.03999999999905"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="68.921875" x="5.5390625" y="3.578125">B-tree A<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n12">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="611.5088000000032" y="426.119999999999"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 15<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n13">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="611.5088000000032" y="396.119999999999"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="67.0859375" x="6.45703125" y="3.578125">B-tree B<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n14">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="23.0" width="80.0" x="611.5088000000032" y="238.11999999999898"/>
+          <y:Fill color="#CCFFCC" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="35.84375" x="22.078125" y="0.078125">r 27<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <node id="n15">
+      <data key="d6">
+        <y:GenericNode configuration="ShinyPlateNodeWithShadow">
+          <y:Geometry height="30.0" width="80.0" x="611.5088000000032" y="208.11999999999898"/>
+          <y:Fill color="#FFFF99" transparent="false"/>
+          <y:BorderStyle color="#800000" type="line" width="2.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="22.84375" modelName="custom" textColor="#000000" visible="true" width="34.8359375" x="22.58203125" y="3.578125">BOB<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+        </y:GenericNode>
+      </data>
+    </node>
+    <edge id="e0" source="n6" target="n1">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="247.25440000000162" y="249.61999999999898"/>
+            <y:Point x="247.25440000000162" y="343.03999999999905"/>
+          </y:Path>
+          <y:LineStyle color="#C0C0C0" type="dashed" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e1" source="n6" target="n3">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="227.25440000000162" y="249.61999999999898"/>
+            <y:Point x="227.25440000000162" y="411.119999999999"/>
+          </y:Path>
+          <y:LineStyle color="#C0C0C0" type="dashed" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e2" source="n6" target="n5">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="205.25440000000162" y="249.61999999999898"/>
+            <y:Point x="205.25440000000162" y="479.1999999999989"/>
+          </y:Path>
+          <y:LineStyle color="#C0C0C0" type="dashed" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e3" source="n9" target="n15">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="479.9240000000027" y="223.11999999999898"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e4" source="n14" target="n11">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="746.1696000000011" y="249.61999999999898"/>
+            <y:Point x="746.1696000000011" y="343.03999999999905"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e5" source="n14" target="n13">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="766.1696000000011" y="249.61999999999898"/>
+            <y:Point x="766.1696000000011" y="411.119999999999"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e6" source="n14" target="n5">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="787.1696000000011" y="249.61999999999898"/>
+            <y:Point x="787.1696000000011" y="479.1999999999989"/>
+          </y:Path>
+          <y:LineStyle color="#000000" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+  </graph>
+  <data key="d0">
+    <y:Resources/>
+  </data>
+</graphml>
diff --git a/mavibot/img/transok.png b/mavibot/img/transok.png
new file mode 100644
index 0000000..8ac423f
--- /dev/null
+++ b/mavibot/img/transok.png
Binary files differ
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java
index 4e05724..1951516 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java
@@ -23,9 +23,13 @@
 import java.io.IOException;
 import java.lang.reflect.Array;
 import java.util.Comparator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
 
+import org.apache.directory.mavibot.btree.exception.BTreeCreationException;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
 
@@ -44,11 +48,8 @@
     /** The read transaction timeout */
     protected long readTimeOut = DEFAULT_READ_TIMEOUT;
 
-    /** The Header for a managed BTree */
-    protected BTreeHeader btreeHeader;
-
-    /** The current rootPage */
-    protected volatile Page<K, V> rootPage;
+    /** The current Header for a managed BTree */
+    protected BTreeHeader<K, V> currentBtreeHeader;
 
     /** The Key serializer used for this tree.*/
     protected ElementSerializer<K> keySerializer;
@@ -62,20 +63,46 @@
     /** The size of the buffer used to write data in disk */
     protected int writeBufferSize;
 
-    /** A lock used to protect the write operation against concurrent access */
-    protected ReentrantLock writeLock;
-
     /** Flag to enable duplicate key support */
-    private boolean allowDuplicates;
+    protected boolean allowDuplicates;
+
+    /** The number of elements in a page for this B-tree */
+    protected int pageSize;
+
+    /** The BTree name */
+    protected String name;
+
+    /** The FQCN of the Key serializer */
+    protected String keySerializerFQCN;
+
+    /** The FQCN of the Value serializer */
+    protected String valueSerializerFQCN;
 
     /** The thread responsible for the cleanup of timed out reads */
     protected Thread readTransactionsThread;
 
     /** The BTree type : either in-memory, disk backed or persisted */
-    private BTreeTypeEnum type;
+    protected BTreeTypeEnum btreeType;
 
     /** The current transaction */
-    protected WriteTransaction writeTransaction;
+    protected AtomicBoolean transactionStarted = new AtomicBoolean( false );
+
+    /** The map of all the used BtreeHeaders */
+    protected Map<Long, BTreeHeader<K, V>> btreeRevisions = new ConcurrentHashMap<Long, BTreeHeader<K, V>>();
+
+    /** The current revision */
+    protected AtomicLong currentRevision = new AtomicLong( 0L );
+    
+    /** The TransactionManager used for this BTree */
+    protected TransactionManager transactionManager;
+
+    /**
+     * Starts a Read Only transaction. If the transaction is not closed, it will be
+     * automatically closed after the timeout
+     *
+     * @return The created transaction
+     */
+    protected abstract ReadTransaction<K, V> beginReadTransaction();
 
 
     /**
@@ -84,33 +111,37 @@
      *
      * @return The created transaction
      */
-    protected ReadTransaction<K, V> beginReadTransaction()
-    {
-        ReadTransaction<K, V> readTransaction = new ReadTransaction<K, V>( rootPage, btreeHeader.getRevision() - 1,
-            System.currentTimeMillis() );
-
-        readTransactions.add( readTransaction );
-
-        return readTransaction;
-    }
+    protected abstract ReadTransaction<K, V> beginReadTransaction( long revision );
 
 
     /**
      * {@inheritDoc}
      */
-    public TupleCursor<K, V> browse() throws IOException
+    public TupleCursor<K, V> browse() throws IOException, KeyNotFoundException
     {
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+        
         ReadTransaction<K, V> transaction = beginReadTransaction();
 
-        // Fetch the root page for this revision
-        ParentPos<K, V>[] stack = (ParentPos<K, V>[]) Array.newInstance( ParentPos.class, 32 );
+        if ( transaction == null )
+        {
+            return new EmptyTupleCursor<K, V>( 0L );
+        }
+        else
+        {
+            ParentPos<K, V>[] stack = (ParentPos<K, V>[]) Array.newInstance( ParentPos.class, 32 );
 
-        TupleCursor<K, V> cursor = rootPage.browse( transaction, stack, 0 );
+            TupleCursor<K, V> cursor = getRootPage().browse( transaction, stack, 0 );
 
-        // Set the position before the first element
-        cursor.beforeFirst();
+            // Set the position before the first element
+            cursor.beforeFirst();
 
-        return cursor;
+            return cursor;
+        }
     }
 
 
@@ -119,17 +150,27 @@
      */
     public TupleCursor<K, V> browse( long revision ) throws IOException, KeyNotFoundException
     {
-        ReadTransaction<K, V> transaction = beginReadTransaction();
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
 
-        // Fetch the root page for this revision
-        Page<K, V> revisionRootPage = getRootPage( revision );
+        ReadTransaction<K, V> transaction = beginReadTransaction( revision );
 
-        ParentPos<K, V>[] stack = (ParentPos<K, V>[]) Array.newInstance( ParentPos.class, 32 );
+        if ( transaction == null )
+        {
+            return new EmptyTupleCursor<K, V>( revision );
+        }
+        else
+        {
+            ParentPos<K, V>[] stack = (ParentPos<K, V>[]) Array.newInstance( ParentPos.class, 32 );
 
-        // And get the cursor
-        TupleCursor<K, V> cursor = revisionRootPage.browse( transaction, stack, 0 );
+            // And get the cursor
+            TupleCursor<K, V> cursor = getRootPage( transaction.getRevision() ).browse( transaction, stack, 0 );
 
-        return cursor;
+            return cursor;
+        }
     }
 
 
@@ -138,14 +179,27 @@
      */
     public TupleCursor<K, V> browseFrom( K key ) throws IOException
     {
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+
         ReadTransaction<K, V> transaction = beginReadTransaction();
 
-        // Fetch the root page for this revision
         ParentPos<K, V>[] stack = (ParentPos<K, V>[]) Array.newInstance( ParentPos.class, 32 );
 
-        TupleCursor<K, V> cursor = rootPage.browse( key, transaction, stack, 0 );
-
-        return cursor;
+        TupleCursor<K, V> cursor;
+        try
+        {
+            cursor = getRootPage( transaction.getRevision() ).browse( key, transaction, stack, 0 );
+            
+            return cursor;
+        }
+        catch ( KeyNotFoundException e )
+        {
+            throw new IOException( e.getMessage() );
+        }
     }
 
 
@@ -154,17 +208,27 @@
      */
     public TupleCursor<K, V> browseFrom( long revision, K key ) throws IOException, KeyNotFoundException
     {
-        ReadTransaction<K, V> transaction = beginReadTransaction();
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
 
-        // Fetch the rootPage for this revision
-        Page<K, V> revisionRootPage = getRootPage( revision );
+        ReadTransaction<K, V> transaction = beginReadTransaction( revision );
 
-        ParentPos<K, V>[] stack = (ParentPos<K, V>[]) Array.newInstance( ParentPos.class, 32 );
+        if ( transaction == null )
+        {
+            return new EmptyTupleCursor<K, V>( revision );
+        }
+        else
+        {
+            ParentPos<K, V>[] stack = (ParentPos<K, V>[]) Array.newInstance( ParentPos.class, 32 );
 
-        // And get the cursor
-        TupleCursor<K, V> cursor = revisionRootPage.browse( key, transaction, stack, 0 );
+            // And get the cursor
+            TupleCursor<K, V> cursor = getRootPage( transaction.getRevision() ).browse( key, transaction, stack, 0 );
 
-        return cursor;
+            return cursor;
+        }
     }
 
 
@@ -173,7 +237,33 @@
      */
     public boolean contains( K key, V value ) throws IOException
     {
-        return rootPage.contains( key, value );
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+
+        ReadTransaction<K, V> transaction = beginReadTransaction();
+
+        if ( transaction == null )
+        {
+            return false;
+        }
+        else
+        {
+            try
+            {
+                return getRootPage( transaction.getRevision() ).contains( key, value );
+            }
+            catch ( KeyNotFoundException knfe )
+            {
+                throw new IOException( knfe.getMessage() );
+            }
+            finally
+            {
+                transaction.close();
+            }
+        }
     }
 
 
@@ -182,10 +272,30 @@
      */
     public boolean contains( long revision, K key, V value ) throws IOException, KeyNotFoundException
     {
-        // Fetch the root page for this revision
-        Page<K, V> revisionRootPage = getRootPage( revision );
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
 
-        return revisionRootPage.contains( key, value );
+        // Fetch the root page for this revision
+        ReadTransaction<K, V> transaction = beginReadTransaction( revision );
+
+        if ( transaction == null )
+        {
+            return false;
+        }
+        else
+        {
+            try
+            {
+                return getRootPage( transaction.getRevision() ).contains( key, value );
+            }
+            finally
+            {
+                transaction.close();
+            }
+        }
     }
 
 
@@ -194,16 +304,36 @@
      */
     public Tuple<K, V> delete( K key ) throws IOException
     {
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+
         if ( key == null )
         {
             throw new IllegalArgumentException( "Key must not be null" );
         }
 
-        long revision = generateRevision();
+        // Take the lock if it's not already taken by another thread
+        transactionManager.beginTransaction();
 
-        Tuple<K, V> deleted = delete( key, revision );
+        try
+        {
+            Tuple<K, V> deleted = delete( key, currentRevision.get() + 1 );
 
-        return deleted;
+            // Commit now
+            transactionManager.commit();
+
+            return deleted;
+        }
+        catch ( IOException ioe )
+        {
+            // We have had an exception, we must rollback the transaction
+            transactionManager.rollback();
+            
+            return null;
+        }
     }
 
 
@@ -212,6 +342,12 @@
      */
     public Tuple<K, V> delete( K key, V value ) throws IOException
     {
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+
         if ( key == null )
         {
             throw new IllegalArgumentException( "Key must not be null" );
@@ -222,11 +358,22 @@
             throw new IllegalArgumentException( "Value must not be null" );
         }
 
-        long revision = generateRevision();
+        transactionManager.beginTransaction();
 
-        Tuple<K, V> deleted = delete( key, value, revision );
-
-        return deleted;
+        try
+        {
+            Tuple<K, V> deleted = delete( key, value, currentRevision.get() + 1 );
+            
+            transactionManager.commit();
+    
+            return deleted;
+        }
+        catch ( IOException ioe )
+        {
+            transactionManager.rollback();
+            
+            throw ioe;
+        }
     }
 
 
@@ -251,34 +398,54 @@
      */
     public V insert( K key, V value ) throws IOException
     {
-        long revision = generateRevision();
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
 
         V existingValue = null;
 
+        if ( key == null )
+        {
+            throw new IllegalArgumentException( "Key must not be null" );
+        }
+
+        // Take the lock if it's not already taken by another thread and if we 
+        // aren't on a sub-btree
+        if ( btreeType != BTreeTypeEnum.PERSISTED_SUB )
+        {
+            transactionManager.beginTransaction();
+        }
+        
         try
         {
-            if ( writeTransaction == null )
-            {
-                writeLock.lock();
-            }
-
-            InsertResult<K, V> result = insert( key, value, revision );
+            InsertResult<K, V> result = insert( key, value, -1L );
 
             if ( result instanceof ModifyResult )
             {
                 existingValue = ( ( ModifyResult<K, V> ) result ).getModifiedValue();
             }
-        }
-        finally
-        {
-            // See above
-            if ( writeTransaction == null )
+            
+            // Commit now if it's not a sub-btree
+            if ( btreeType != BTreeTypeEnum.PERSISTED_SUB )
             {
-                writeLock.unlock();
+                transactionManager.commit();
             }
+    
+            return existingValue;
         }
-
-        return existingValue;
+        catch ( IOException ioe )
+        {
+            // We have had an exception, we must rollback the transaction
+            // if it's not a sub-btree
+            if ( btreeType != BTreeTypeEnum.PERSISTED_SUB )
+            {
+                transactionManager.rollback();
+            }
+            
+            return null;
+        }
     }
 
 
@@ -302,7 +469,29 @@
      */
     public V get( K key ) throws IOException, KeyNotFoundException
     {
-        return rootPage.get( key );
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+
+        ReadTransaction<K, V> transaction = beginReadTransaction();
+
+        if ( transaction == null )
+        {
+            return null;
+        }
+        else
+        {
+            try
+            {
+                return getRootPage( transaction.getRevision() ).get( key );
+            }
+            finally
+            {
+                transaction.close();
+            }
+        }
     }
 
 
@@ -311,29 +500,42 @@
      */
     public V get( long revision, K key ) throws IOException, KeyNotFoundException
     {
-        // Fetch the root page for this revision
-        Page<K, V> revisionRootPage = getRootPage( revision );
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
 
-        return revisionRootPage.get( key );
+        ReadTransaction<K, V> transaction = beginReadTransaction( revision );
+
+        if ( transaction == null )
+        {
+            return null;
+        }
+        else
+        {
+            try
+            {
+                return getRootPage( transaction.getRevision() ).get( key );
+            }
+            finally
+            {
+                transaction.close();
+            }
+        }
     }
 
 
     /**
      * {@inheritDoc}
      */
-    public Page<K, V> getRootPage()
-    {
-        return rootPage;
-    }
+    public abstract Page<K, V> getRootPage();
 
 
     /**
      * {@inheritDoc}
      */
-    /* no qualifier */void setRootPage( Page<K, V> root )
-    {
-        rootPage = root;
-    }
+    /* no qualifier */abstract void setRootPage( Page<K, V> root );
 
 
     /**
@@ -341,21 +543,65 @@
      */
     public ValueCursor<V> getValues( K key ) throws IOException, KeyNotFoundException
     {
-        return rootPage.getValues( key );
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+
+        ReadTransaction<K, V> transaction = beginReadTransaction();
+
+        if ( transaction == null )
+        {
+            return new EmptyValueCursor<V>( 0L );
+        }
+        else
+        {
+            try
+            {
+                return getRootPage( transaction.getRevision() ).getValues( key );
+            }
+            finally
+            {
+                transaction.close();
+            }
+        }
     }
 
 
     /**
      * {@inheritDoc}
      */
-    public boolean hasKey( K key ) throws IOException
+    public boolean hasKey( K key ) throws IOException, KeyNotFoundException
     {
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+
         if ( key == null )
         {
             return false;
         }
 
-        return rootPage.hasKey( key );
+        ReadTransaction<K, V> transaction = beginReadTransaction();
+
+        if ( transaction == null )
+        {
+            return false;
+        }
+        else
+        {
+            try
+            {
+                return getRootPage( transaction.getRevision() ).hasKey( key );
+            }
+            finally
+            {
+                transaction.close();
+            }
+        }
     }
 
 
@@ -364,15 +610,34 @@
      */
     public boolean hasKey( long revision, K key ) throws IOException, KeyNotFoundException
     {
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+
         if ( key == null )
         {
             return false;
         }
 
-        // Fetch the root page for this revision
-        Page<K, V> revisionRootPage = getRootPage( revision );
+        ReadTransaction<K, V> transaction = beginReadTransaction( revision );
 
-        return revisionRootPage.hasKey( key );
+        if ( transaction == null )
+        {
+            return false;
+        }
+        else
+        {
+            try
+            {
+                return getRootPage( transaction.getRevision() ).hasKey( key );
+            }
+            finally
+            {
+                transaction.close();
+            }
+        }
     }
 
 
@@ -391,7 +656,7 @@
     public void setKeySerializer( ElementSerializer<K> keySerializer )
     {
         this.keySerializer = keySerializer;
-        btreeHeader.setKeySerializerFQCN( keySerializer.getClass().getName() );
+        keySerializerFQCN = keySerializer.getClass().getName();
     }
 
 
@@ -400,7 +665,7 @@
      */
     public String getKeySerializerFQCN()
     {
-        return btreeHeader.getKeySerializerFQCN();
+        return keySerializerFQCN;
     }
 
 
@@ -419,7 +684,7 @@
     public void setValueSerializer( ElementSerializer<V> valueSerializer )
     {
         this.valueSerializer = valueSerializer;
-        btreeHeader.setValueSerializerFQCN( valueSerializer.getClass().getName() );
+        valueSerializerFQCN = valueSerializer.getClass().getName();
     }
 
 
@@ -428,7 +693,7 @@
      */
     public String getValueSerializerFQCN()
     {
-        return btreeHeader.getValueSerializerFQCN();
+        return valueSerializerFQCN;
     }
 
 
@@ -437,7 +702,29 @@
      */
     public long getRevision()
     {
-        return btreeHeader.getRevision();
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+
+        ReadTransaction<K, V> transaction = beginReadTransaction();
+
+        if ( transaction == null )
+        {
+            return -1L;
+        }
+        else
+        {
+            try
+            {
+                return transaction.getRevision();
+            }
+            finally
+            {
+                transaction.close();
+            }
+        }
     }
 
 
@@ -446,18 +733,56 @@
      */
     /* no qualifier */void setRevision( long revision )
     {
-        btreeHeader.setRevision( revision );
+        transactionManager.getBTreeHeader( getName() ).setRevision( revision );
     }
 
 
     /**
-     * Generates a new revision number. It's only used by the Page instances.
-     *
-     * @return a new incremental revision number
+     * Store the new revision in the map of btrees, increment the current revision
      */
-    /* no qualifier */long generateRevision()
+    protected void storeRevision( BTreeHeader<K, V> btreeHeader, boolean keepRevisions )
     {
-        return btreeHeader.incrementRevision();
+        long revision = btreeHeader.getRevision();
+
+        if ( keepRevisions )
+        {
+            synchronized ( btreeRevisions )
+            {
+                btreeRevisions.put( revision, btreeHeader );
+            }
+        }
+
+        currentRevision.set( revision );
+        currentBtreeHeader = btreeHeader;
+        
+        // And update the newBTreeHeaders map
+        if ( btreeHeader.getBtree().getType() != BTreeTypeEnum.PERSISTED_SUB )
+        {
+            transactionManager.updateNewBTreeHeaders( btreeHeader );
+        }
+    }
+
+
+    /**
+     * Store the new revision in the map of btrees, increment the current revision
+     */
+    protected void storeRevision( BTreeHeader<K, V> btreeHeader )
+    {
+        long revision = btreeHeader.getRevision();
+
+        synchronized ( btreeRevisions )
+        {
+            btreeRevisions.put( revision, btreeHeader );
+        }
+
+        currentRevision.set( revision );
+        currentBtreeHeader = btreeHeader;
+        
+        // And update the newBTreeHeaders map
+        if ( btreeHeader.getBtree().getType() != BTreeTypeEnum.PERSISTED_SUB )
+        {
+            transactionManager.updateNewBTreeHeaders( btreeHeader );
+        }
     }
 
 
@@ -484,7 +809,29 @@
      */
     public long getNbElems()
     {
-        return btreeHeader.getNbElems();
+        // Check that we have a TransactionManager
+        if ( transactionManager == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+
+        ReadTransaction<K, V> transaction = beginReadTransaction();
+
+        if ( transaction == null )
+        {
+            return -1L;
+        }
+        else
+        {
+            try
+            {
+                return transaction.getBtreeHeader().getNbElems();
+            }
+            finally
+            {
+                transaction.close();
+            }
+        }
     }
 
 
@@ -493,7 +840,7 @@
      */
     /* no qualifier */void setNbElems( long nbElems )
     {
-        btreeHeader.setNbElems( nbElems );
+        transactionManager.getBTreeHeader( getName() ).setNbElems( nbElems );
     }
 
 
@@ -502,7 +849,7 @@
      */
     public int getPageSize()
     {
-        return btreeHeader.getPageSize();
+        return pageSize;
     }
 
 
@@ -513,11 +860,11 @@
     {
         if ( pageSize <= 2 )
         {
-            btreeHeader.setPageSize( DEFAULT_PAGE_SIZE );
+            this.pageSize = DEFAULT_PAGE_SIZE;
         }
         else
         {
-            btreeHeader.setPageSize( getPowerOf2( pageSize ) );
+            this.pageSize = getPowerOf2( pageSize );
         }
     }
 
@@ -527,7 +874,7 @@
      */
     public String getName()
     {
-        return btreeHeader.getName();
+        return name;
     }
 
 
@@ -536,7 +883,7 @@
      */
     public void setName( String name )
     {
-        btreeHeader.setName( name );
+        this.name = name;
     }
 
 
@@ -572,7 +919,7 @@
      */
     public boolean isAllowDuplicates()
     {
-        return btreeHeader.isAllowDuplicates();
+        return allowDuplicates;
     }
 
 
@@ -581,7 +928,7 @@
      */
     public void setAllowDuplicates( boolean allowDuplicates )
     {
-        btreeHeader.setAllowDuplicates( allowDuplicates );
+        this.allowDuplicates = allowDuplicates;
     }
 
 
@@ -590,7 +937,7 @@
      */
     public BTreeTypeEnum getType()
     {
-        return type;
+        return btreeType;
     }
 
 
@@ -599,7 +946,7 @@
      */
     public void setType( BTreeTypeEnum type )
     {
-        this.type = type;
+        this.btreeType = type;
     }
 
 
@@ -621,6 +968,24 @@
 
 
     /**
+     * @return The current BtreeHeader
+     */
+    protected BTreeHeader<K, V> getBtreeHeader()
+    {
+        return currentBtreeHeader;
+    }
+
+
+    /**
+     * @return The current BtreeHeader
+     */
+    protected BTreeHeader<K, V> getBtreeHeader( long revision )
+    {
+        return btreeRevisions.get( revision );
+    }
+
+
+    /**
      * Create a thread that is responsible of cleaning the transactions when
      * they hit the timeout
      */
@@ -657,6 +1022,12 @@
                             {
                                 transaction.close();
                                 readTransactions.poll();
+
+                                synchronized ( btreeRevisions )
+                                {
+                                    btreeRevisions.remove( transaction.getRevision() );
+                                }
+
                                 continue;
                             }
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java
index 168f078..b5458b1 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java
@@ -23,8 +23,6 @@
 import java.io.IOException;
 import java.lang.reflect.Array;
 
-import org.apache.directory.mavibot.btree.KeyHolder;
-import org.apache.directory.mavibot.btree.Page;
 import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 
@@ -32,7 +30,7 @@
 /**
  * A MVCC abstract Page. It stores the field and the methods shared by the Node and Leaf
  * classes.
- * 
+ *
  * @param <K> The type for the Key
  * @param <V> The type for the stored value
  *
@@ -61,14 +59,9 @@
     /** The last {@link PageIO} storing the serialized Page on disk */
     protected long lastOffset = -1L;
 
-    /** A static Exception used to avoid creating a new one every time */
-    protected KeyNotFoundException KEY_NOT_FOUND_EXCEPTION = new KeyNotFoundException(
-        "Cannot find an entry associated with this key" );
-
-
     /**
      * Creates a default empty AbstractPage
-     * 
+     *
      * @param btree The associated BTree
      */
     protected AbstractPage( BTree<K, V> btree )
@@ -216,6 +209,30 @@
     /**
      * {@inheritDoc}
      */
+    public DeleteResult<K, V> delete( K key, V value, long revision ) throws IOException
+    {
+        return delete( key, value, revision, null, -1 );
+    }
+
+
+    /**
+     * The real delete implementation. It can be used for internal deletion in the B-tree.
+     *
+     * @param key The key to delete
+     * @param value The value to delete
+     * @param revision The revision for which we want to delete a tuple
+     * @param parent The parent page
+     * @param parentPos The position of this page in the parent page
+     * @return The result
+     * @throws IOException If we had an issue while processing the deletion
+     */
+    /* no qualifier */abstract DeleteResult<K, V> delete( K key, V value, long revision, Page<K, V> parent, int parentPos )
+        throws IOException;
+
+
+    /**
+     * {@inheritDoc}
+     */
     public V get( K key ) throws IOException, KeyNotFoundException
     {
         int pos = findPos( key );
@@ -299,7 +316,7 @@
     /**
      * Selects the sibling (the previous or next page with the same parent) which has
      * the more element assuming it's above N/2
-     * 
+     *
      * @param parent The parent of the current page
      * @param The position of the current page reference in its parent
      * @return The position of the sibling, or -1 if we have'nt found any sibling
@@ -403,7 +420,7 @@
 
     /**
      * Sets the key at a give position
-     * 
+     *
      * @param pos The position in the keys array
      * @param key the key to inject
      */
@@ -452,7 +469,7 @@
 
     /**
      * Compares two keys
-     * 
+     *
      * @param key1 The first key
      * @param key2 The second key
      * @return -1 if the first key is above the second one, 1 if it's below, and 0
@@ -510,8 +527,8 @@
      * <li>'h' will return -4</li>
      * <li>'i' will return 4</li>
      * </ul>
-     * 
-     * 
+     *
+     *
      * @param key The key to find
      * @return The position in the page.
      */
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransactionManager.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransactionManager.java
new file mode 100644
index 0000000..4ac5c52
--- /dev/null
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransactionManager.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree;
+
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * An abstract class implementing the TransactionManager interface.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public abstract class AbstractTransactionManager implements TransactionManager
+{
+    /** A lock to protect the transaction handling */
+    private ReadWriteLock transactionLock = new ReentrantReadWriteLock();
+}
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractValueHolder.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractValueHolder.java
index 4da7f76..053d3e1 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractValueHolder.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractValueHolder.java
@@ -24,6 +24,7 @@
 import java.lang.reflect.Array;
 import java.util.Comparator;
 
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
 
 
@@ -244,6 +245,10 @@
             e.printStackTrace();
             return false;
         }
+        catch ( KeyNotFoundException knfe )
+        {
+            knfe.printStackTrace();return false;
+        }
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java
index af3a66b..972377c 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java
@@ -28,7 +28,7 @@
 
 
 /**
- * A BTree interface, to be implemented by the PersistedBTree or the InMemoryBTree
+ * A B-tree interface, to be implemented by the PersistedBTree or the InMemoryBTree
  *
  * @param <K> The Key type
  * @param <V> The Value type
@@ -46,23 +46,15 @@
     /** Define a default delay for a read transaction. This is 10 seconds */
     static final long DEFAULT_READ_TIMEOUT = 10 * 1000L;
 
-    /** The BTree allows duplicate values */
+    /** The B-tree allows duplicate values */
     static final boolean ALLOW_DUPLICATES = true;
 
-    /** The BTree forbids duplicate values */
+    /** The B-tree forbids duplicate values */
     static final boolean FORBID_DUPLICATES = false;
 
 
     /**
-     * Initialize the BTree.
-     *
-     * @throws IOException If we get some exception while initializing the BTree
-     */
-    void init() throws IOException;
-
-
-    /**
-     * Close the BTree, cleaning up all the data structure
+     * Close the B-tree, cleaning up all the data structure
      */
     void close() throws IOException;
 
@@ -87,10 +79,10 @@
 
 
     /**
-     * Insert an entry in the BTree.
+     * Insert an entry in the B-tree.
      * <p>
      * We will replace the value if the provided key already exists in the
-     * btree.
+     * B-tree.
      *
      * @param key Inserted key
      * @param value Inserted value
@@ -130,7 +122,7 @@
      *
      * @param key The key we are looking at
      * @return The found value, or null if the key is not present in the tree
-     * @throws KeyNotFoundException If the key is not found in the BTree
+     * @throws KeyNotFoundException If the key is not found in the B-tree
      * @throws IOException TODO
      */
     V get( K key ) throws IOException, KeyNotFoundException;
@@ -142,7 +134,7 @@
      * @param revision The revision we are looking for
      * @return The rootPage associated to this revision
      * @throws IOException If we had an issue while accessing the underlying file
-     * @throws KeyNotFoundException If the revision does not exist for this Btree
+     * @throws KeyNotFoundException If the revision does not exist for this B-tree
      */
     Page<K, V> getRootPage( long revision ) throws IOException, KeyNotFoundException;
 
@@ -169,7 +161,7 @@
      * @param revision The revision for which we want to find a key
      * @param key The key we are looking at
      * @return The found value, or null if the key is not present in the tree
-     * @throws KeyNotFoundException If the key is not found in the BTree
+     * @throws KeyNotFoundException If the key is not found in the B-tree
      * @throws IOException If there was an issue while fetching data from the disk
      */
     V get( long revision, K key ) throws IOException, KeyNotFoundException;
@@ -181,8 +173,9 @@
      * @param key The key we are looking at
      * @return true if the key is present, false otherwise
      * @throws IOException If we have an error while trying to access the page
+     * @throws KeyNotFoundException If the key is not found in the B-tree
      */
-    boolean hasKey( K key ) throws IOException;
+    boolean hasKey( K key ) throws IOException, KeyNotFoundException;
 
 
     /**
@@ -192,13 +185,13 @@
      * @param key The key we are looking at
      * @return true if the key is present, false otherwise
      * @throws IOException If we have an error while trying to access the page
-     * @throws KeyNotFoundException If the key is not found in the BTree
+     * @throws KeyNotFoundException If the key is not found in the B-tree
      */
     boolean hasKey( long revision, K key ) throws IOException, KeyNotFoundException;
 
 
     /**
-     * Checks if the BTree contains the given key with the given value.
+     * Checks if the B-tree contains the given key with the given value.
      *
      * @param key The key we are looking for
      * @param value The value associated with the given key
@@ -208,13 +201,13 @@
 
 
     /**
-     * Checks if the BTree contains the given key with the given value for a given revision
+     * Checks if the B-tree contains the given key with the given value for a given revision
      *
      * @param revision The revision we would like to browse
      * @param key The key we are looking for
      * @param value The value associated with the given key
      * @return true if the key and value are associated with each other, false otherwise
-     * @throws KeyNotFoundException If the key is not found in the BTree
+     * @throws KeyNotFoundException If the key is not found in the B-tree
      */
     boolean contains( long revision, K key, V value ) throws IOException, KeyNotFoundException;
 
@@ -222,19 +215,19 @@
     /**
      * Creates a cursor starting at the beginning of the tree
      *
-     * @return A cursor on the btree
+     * @return A cursor on the B-tree
      * @throws IOException
      */
-    TupleCursor<K, V> browse() throws IOException;
+    TupleCursor<K, V> browse() throws IOException, KeyNotFoundException;
 
 
     /**
      * Creates a cursor starting at the beginning of the tree, for a given revision
      *
      * @param revision The revision we would like to browse
-     * @return A cursor on the btree
+     * @return A cursor on the B-tree
      * @throws IOException If we had an issue while fetching data from the disk
-     * @throws KeyNotFoundException If the key is not found in the BTree
+     * @throws KeyNotFoundException If the key is not found in the B-tree
      */
     TupleCursor<K, V> browse( long revision ) throws IOException, KeyNotFoundException;
 
@@ -244,7 +237,7 @@
      *
      * @param key The key which is the starting point. If the key is not found,
      * then the cursor will always return null.
-     * @return A cursor on the btree
+     * @return A cursor on the B-tree
      * @throws IOException
      */
     TupleCursor<K, V> browseFrom( K key ) throws IOException;
@@ -256,8 +249,8 @@
      * @param The revision we are looking for
      * @param key The key which is the starting point. If the key is not found,
      * then the cursor will always return null.
-     * @return A cursor on the btree
-     * @throws IOException If wxe had an issue reading the BTree from disk
+     * @return A cursor on the B-tree
+     * @throws IOException If wxe had an issue reading the B-tree from disk
      * @throws KeyNotFoundException  If we can't find a rootPage for this revision
      */
     TupleCursor<K, V> browseFrom( long revision, K key ) throws IOException, KeyNotFoundException;
@@ -349,25 +342,25 @@
 
 
     /**
-     * @return The current BTree revision
+     * @return The current B-tree revision
      */
     long getRevision();
 
 
     /**
-     * @return The current number of elements in the BTree
+     * @return The current number of elements in the B-tree
      */
     long getNbElems();
 
 
     /**
-     * @return true if this BTree allow duplicate values
+     * @return true if this B-tree allow duplicate values
      */
     boolean isAllowDuplicates();
 
 
     /**
-     * @param allowDuplicates True if the BTree will allow duplicate values
+     * @param allowDuplicates True if the B-tree will allow duplicate values
      */
     void setAllowDuplicates( boolean allowDuplicates );
 
@@ -376,22 +369,4 @@
      * @return the type
      */
     BTreeTypeEnum getType();
-
-
-    /**
-     * Starts a transaction
-     */
-    void beginTransaction();
-
-
-    /**
-     * Commits a transaction
-     */
-    void commit();
-
-
-    /**
-     * Rollback a transaction
-     */
-    void rollback();
 }
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java
index 7a93d63..3bdd4f4 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java
@@ -20,31 +20,31 @@
 package org.apache.directory.mavibot.btree;
 
 
-import java.io.IOException;
 import java.util.LinkedList;
 
 import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
 
 
 /**
- * This class construct a BTree from a serialized version of a BTree. We need it
- * to avoid exposing all the methods of the BTree class.<br>
- * 
+ * This class construct a B-tree from a serialized version of a B-tree. We need it
+ * to avoid exposing all the methods of the B-tree class.<br>
+ *
  * All its methods are static.
- *  
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  *
- * @param <K> The BTree key type
- * @param <V> The BTree valye type
+ * @param <K> The B-tree key type
+ * @param <V> The B-tree value type
  */
 public class BTreeFactory<K, V>
 {
     //--------------------------------------------------------------------------------------------
     // Create persisted btrees
     //--------------------------------------------------------------------------------------------
-
     /**
-     * Creates a new persisted BTree, with no initialization. 
+     * Creates a new persisted B-tree, with no initialization.
+     *
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createPersistedBTree()
     {
@@ -55,10 +55,36 @@
 
 
     /**
-     * Creates a new persisted BTree using the BTreeConfiguration to initialize the 
-     * BTree
-     * 
+     * Creates a new persisted B-tree, with no initialization.
+     *
+     * @return a new B-tree instance
+     */
+    public static <K, V> BTree<K, V> createPersistedBTree( BTreeTypeEnum type )
+    {
+        BTree<K, V> btree = new PersistedBTree<K, V>();
+        ((AbstractBTree<K, V>)btree).setType( type );
+
+        return btree;
+    }
+
+
+    /**
+     * Sets the btreeHeader offset for a Persisted BTree
+     *
+     * @param btree The btree to update
+     * @param btreeHeaderOffset The offset
+     */
+    public static <K, V> void setBtreeHeaderOffset( PersistedBTree<K, V> btree, long btreeHeaderOffset )
+    {
+        btree.setBtreeHeaderOffset( btreeHeaderOffset );
+    }
+
+    /**
+     * Creates a new persisted B-tree using the BTreeConfiguration to initialize the
+     * B-tree
+     *
      * @param configuration The configuration to use
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createPersistedBTree( PersistedBTreeConfiguration<K, V> configuration )
     {
@@ -69,14 +95,13 @@
 
 
     /**
-     * Creates a new persisted BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new persisted B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
-     * @param allowDuplicates Tells if the BTree allows multiple value for a given key
-     * @throws IOException
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
         ElementSerializer<V> valueSerializer )
@@ -98,14 +123,14 @@
 
 
     /**
-     * Creates a new persisted BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new persisted B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
-     * @param allowDuplicates Tells if the BTree allows multiple value for a given key
-     * @throws IOException
+     * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
         ElementSerializer<V> valueSerializer, boolean allowDuplicates )
@@ -127,15 +152,15 @@
 
 
     /**
-     * Creates a new persisted BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new persisted B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
-     * @param allowDuplicates Tells if the BTree allows multiple value for a given key
-     * @param cacheSize The size to be used for this BTree cache
-     * @throws IOException
+     * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+     * @param cacheSize The size to be used for this B-tree cache
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
         ElementSerializer<V> valueSerializer, boolean allowDuplicates, int cacheSize )
@@ -157,14 +182,14 @@
 
 
     /**
-     * Creates a new persisted BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new persisted B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
      * @param pageSize Size of the page
-     * @throws IOException
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
         ElementSerializer<V> valueSerializer, int pageSize )
@@ -186,15 +211,15 @@
 
 
     /**
-     * Creates a new persisted BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new persisted B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
      * @param pageSize Size of the page
-     * @param allowDuplicates Tells if the BTree allows multiple value for a given key
-     * @throws IOException
+     * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
         ElementSerializer<V> valueSerializer, int pageSize, boolean allowDuplicates )
@@ -216,16 +241,16 @@
 
 
     /**
-     * Creates a new persisted BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new persisted B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
      * @param pageSize Size of the page
-     * @param allowDuplicates Tells if the BTree allows multiple value for a given key
-     * @param cacheSize The size to be used for this BTree cache
-     * @throws IOException
+     * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+     * @param cacheSize The size to be used for this B-tree cache
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
         ElementSerializer<V> valueSerializer, int pageSize, boolean allowDuplicates, int cacheSize )
@@ -247,10 +272,12 @@
 
 
     //--------------------------------------------------------------------------------------------
-    // Create in-memory btrees
+    // Create in-memory B-trees
     //--------------------------------------------------------------------------------------------
     /**
-     * Creates a new in-memory BTree, with no initialization. 
+     * Creates a new in-memory B-tree, with no initialization.
+     *
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createInMemoryBTree()
     {
@@ -261,10 +288,11 @@
 
 
     /**
-     * Creates a new in-memory BTree using the BTreeConfiguration to initialize the 
-     * BTree
-     * 
+     * Creates a new in-memory B-tree using the BTreeConfiguration to initialize the
+     * B-tree
+     *
      * @param configuration The configuration to use
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createInMemoryBTree( InMemoryBTreeConfiguration<K, V> configuration )
     {
@@ -275,12 +303,13 @@
 
 
     /**
-     * Creates a new in-memory BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new in-memory B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createInMemoryBTree( String name, ElementSerializer<K> keySerializer,
         ElementSerializer<V> valueSerializer )
@@ -301,14 +330,14 @@
 
 
     /**
-     * Creates a new in-memory BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new in-memory B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
-     * @param allowDuplicates Tells if the BTree allows multiple value for a given key
-     * @throws IOException
+     * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createInMemoryBTree( String name, ElementSerializer<K> keySerializer,
         ElementSerializer<V> valueSerializer, boolean allowDuplicates )
@@ -329,14 +358,14 @@
 
 
     /**
-     * Creates a new in-memory BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new in-memory B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
      * @param pageSize Size of the page
-     * @throws IOException
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createInMemoryBTree( String name, ElementSerializer<K> keySerializer,
         ElementSerializer<V> valueSerializer, int pageSize )
@@ -357,14 +386,14 @@
 
 
     /**
-     * Creates a new in-memory BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new in-memory B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param filePath The name of the data directory with absolute path
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
-     * @throws IOException
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createInMemoryBTree( String name, String filePath,
         ElementSerializer<K> keySerializer,
@@ -387,19 +416,18 @@
 
 
     /**
-     * Creates a new in-memory BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new in-memory B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param filePath The name of the data directory with absolute path
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
      * @param pageSize Size of the page
-     * @throws IOException
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createInMemoryBTree( String name, String filePath,
-        ElementSerializer<K> keySerializer,
-        ElementSerializer<V> valueSerializer, int pageSize )
+        ElementSerializer<K> keySerializer, ElementSerializer<V> valueSerializer, int pageSize )
     {
         InMemoryBTreeConfiguration<K, V> configuration = new InMemoryBTreeConfiguration<K, V>();
 
@@ -418,16 +446,16 @@
 
 
     /**
-     * Creates a new in-memory BTree using the parameters to initialize the 
-     * BTree
-     * 
-     * @param name The BTree's name
+     * Creates a new in-memory B-tree using the parameters to initialize the
+     * B-tree
+     *
+     * @param name The B-tree's name
      * @param filePath The name of the data directory with absolute path
      * @param keySerializer Key serializer
      * @param valueSerializer Value serializer
      * @param pageSize Size of the page
-     * @param allowDuplicates Tells if the BTree allows multiple value for a given key
-     * @throws IOException
+     * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+     * @return a new B-tree instance
      */
     public static <K, V> BTree<K, V> createInMemoryBTree( String name, String filePath,
         ElementSerializer<K> keySerializer,
@@ -453,17 +481,17 @@
     // Create Pages
     //--------------------------------------------------------------------------------------------
     /**
-     * Create a new Leaf for the given BTree.
-     * 
-     * @param btree The BTree which will contain this leaf
+     * Create a new Leaf for the given B-tree.
+     *
+     * @param btree The B-tree which will contain this leaf
      * @param revision The Leaf's revision
      * @param nbElems The number or elements in this leaf
-     * 
+     *
      * @return A Leaf instance
      */
     /* no qualifier*/static <K, V> Page<K, V> createLeaf( BTree<K, V> btree, long revision, int nbElems )
     {
-        if ( btree.getType() == BTreeTypeEnum.PERSISTED )
+        if ( btree.getType() != BTreeTypeEnum.IN_MEMORY )
         {
             return new PersistedLeaf<K, V>( btree, revision, nbElems );
         }
@@ -475,16 +503,16 @@
 
 
     /**
-     * Create a new Node for the given BTree.
-     * 
-     * @param btree The BTree which will contain this node
+     * Create a new Node for the given B-tree.
+     *
+     * @param btree The B-tree which will contain this node
      * @param revision The Node's revision
      * @param nbElems The number or elements in this node
      * @return A Node instance
      */
     /* no qualifier*/static <K, V> Page<K, V> createNode( BTree<K, V> btree, long revision, int nbElems )
     {
-        if ( btree.getType() == BTreeTypeEnum.PERSISTED )
+        if ( btree.getType() != BTreeTypeEnum.IN_MEMORY )
         {
             return new PersistedNode<K, V>( btree, revision, nbElems );
         }
@@ -500,8 +528,8 @@
     //--------------------------------------------------------------------------------------------
     /**
      * Set the key at a give position
-     * 
-     * @param btree The BTree to update
+     *
+     * @param btree The B-tree to update
      * @param page The page to update
      * @param pos The position in the keys array
      * @param key The key to inject
@@ -510,7 +538,7 @@
     {
         KeyHolder<K> keyHolder;
 
-        if ( btree.getType() == BTreeTypeEnum.PERSISTED )
+        if ( btree.getType() != BTreeTypeEnum.IN_MEMORY )
         {
             keyHolder = new PersistedKeyHolder<K>( btree.getKeySerializer(), key );
         }
@@ -525,12 +553,15 @@
 
     /**
      * Set the value at a give position
+     *
+     * @param btree The B-tree to update
+     * @param page The page to update
      * @param pos The position in the values array
      * @param value the value to inject
      */
     /* no qualifier*/static <K, V> void setValue( BTree<K, V> btree, Page<K, V> page, int pos, ValueHolder<V> value )
     {
-        if ( btree.getType() == BTreeTypeEnum.PERSISTED )
+        if ( btree.getType() != BTreeTypeEnum.IN_MEMORY )
         {
             ( ( PersistedLeaf<K, V> ) page ).setValue( pos, value );
         }
@@ -543,15 +574,15 @@
 
     /**
      * Set the page at a give position
-     * 
-     * @param btree The BTree to update
+     *
+     * @param btree The B-tree to update
      * @param page The page to update
      * @param pos The position in the values array
-     * @param value the value to inject
+     * @param child the child page to inject
      */
     /* no qualifier*/static <K, V> void setPage( BTree<K, V> btree, Page<K, V> page, int pos, Page<K, V> child )
     {
-        if ( btree.getType() == BTreeTypeEnum.PERSISTED )
+        if ( btree.getType() != BTreeTypeEnum.IN_MEMORY )
         {
             ( ( PersistedNode<K, V> ) page ).setValue( pos, new PersistedPageHolder<K, V>( btree, child ) );
         }
@@ -563,42 +594,76 @@
 
 
     //--------------------------------------------------------------------------------------------
-    // Update BTree
+    // Update B-tree
     //--------------------------------------------------------------------------------------------
     /**
-     * Sets the KeySerializer into the BTree
-     *  
-     * @param btree The BTree to update
+     * Sets the KeySerializer into the B-tree
+     *
+     * @param btree The B-tree to update
      * @param keySerializerFqcn the Key serializer FQCN to set
-     * @throws ClassNotFoundException
-     * @throws InstantiationException 
-     * @throws IllegalAccessException
+     * @throws ClassNotFoundException If the key serializer class cannot be found
+     * @throws InstantiationException If the key serializer class cannot be instanciated
+     * @throws IllegalAccessException If the key serializer class cannot be accessed
+     * @throws NoSuchFieldException
+     * @throws SecurityException
+     * @throws IllegalArgumentException
      */
     /* no qualifier*/static <K, V> void setKeySerializer( BTree<K, V> btree, String keySerializerFqcn )
-        throws ClassNotFoundException, IllegalAccessException, InstantiationException
+        throws ClassNotFoundException, IllegalAccessException, InstantiationException, IllegalArgumentException, SecurityException, NoSuchFieldException
     {
         Class<?> keySerializer = Class.forName( keySerializerFqcn );
         @SuppressWarnings("unchecked")
-        ElementSerializer<K> instance = ( ElementSerializer<K> ) keySerializer.newInstance();
+        ElementSerializer<K> instance = null;
+        try
+        {
+            instance = ( ElementSerializer<K> ) keySerializer.getDeclaredField( "INSTANCE" ).get( null );
+        }
+        catch( NoSuchFieldException e )
+        {
+            // ignore
+        }
+
+        if ( instance == null )
+        {
+            instance = ( ElementSerializer<K> ) keySerializer.newInstance();
+        }
+
         btree.setKeySerializer( instance );
     }
 
 
     /**
-     * Sets the ValueSerializer into the BTree
-     *  
-     * @param btree The BTree to update
+     * Sets the ValueSerializer into the B-tree
+     *
+     * @param btree The B-tree to update
      * @param valueSerializerFqcn the Value serializer FQCN to set
-     * @throws ClassNotFoundException
-     * @throws InstantiationException 
-     * @throws IllegalAccessException
+     * @throws ClassNotFoundException If the value serializer class cannot be found
+     * @throws InstantiationException If the value serializer class cannot be instanciated
+     * @throws IllegalAccessException If the value serializer class cannot be accessed
+     * @throws NoSuchFieldException
+     * @throws SecurityException
+     * @throws IllegalArgumentException
      */
     /* no qualifier*/static <K, V> void setValueSerializer( BTree<K, V> btree, String valueSerializerFqcn )
-        throws ClassNotFoundException, IllegalAccessException, InstantiationException
+        throws ClassNotFoundException, IllegalAccessException, InstantiationException, IllegalArgumentException, SecurityException, NoSuchFieldException
     {
         Class<?> valueSerializer = Class.forName( valueSerializerFqcn );
         @SuppressWarnings("unchecked")
-        ElementSerializer<V> instance = ( ElementSerializer<V> ) valueSerializer.newInstance();
+        ElementSerializer<V> instance = null;
+        try
+        {
+            instance = ( ElementSerializer<V> ) valueSerializer.getDeclaredField( "INSTANCE" ).get( null );
+        }
+        catch( NoSuchFieldException e )
+        {
+            // ignore
+        }
+        
+        if ( instance == null )
+        {
+            instance = ( ElementSerializer<V> ) valueSerializer.newInstance();
+        }
+        
         btree.setValueSerializer( instance );
     }
 
@@ -606,8 +671,8 @@
     /**
      * Set the new root page for this tree. Used for debug purpose only. The revision
      * will always be 0;
-     * 
-     * @param btree The BTree to update
+     *
+     * @param btree The B-tree to update
      * @param root the new root page.
      */
     /* no qualifier*/static <K, V> void setRootPage( BTree<K, V> btree, Page<K, V> root )
@@ -617,9 +682,9 @@
 
 
     /**
-     * Return the BTree root page
-     * 
-     * @param btree The Btree we want to root page from
+     * Return the B-tree root page
+     *
+     * @param btree The B-tree we want to root page from
      * @return The root page
      */
     /* no qualifier */static <K, V> Page<K, V> getRootPage( BTree<K, V> btree )
@@ -629,9 +694,9 @@
 
 
     /**
-     * update the BTree number of elements
-     * 
-     * @param btree The BTree to update
+     * Update the B-tree number of elements
+     *
+     * @param btree The B-tree to update
      * @param nbElems the nbElems to set
      */
     /* no qualifier */static <K, V> void setNbElems( BTree<K, V> btree, long nbElems )
@@ -641,9 +706,9 @@
 
 
     /**
-     * Update the btree revision
-     * 
-     * @param btree The BTree to update
+     * Update the B-tree revision
+     *
+     * @param btree The B-tree to update
      * @param revision the revision to set
      */
     /* no qualifier*/static <K, V> void setRevision( BTree<K, V> btree, long revision )
@@ -653,9 +718,9 @@
 
 
     /**
-     * Set the BTree name
-     * 
-     * @param btree The BTree to update
+     * Set the B-tree name
+     *
+     * @param btree The B-tree to update
      * @param name the name to set
      */
     /* no qualifier */static <K, V> void setName( BTree<K, V> btree, String name )
@@ -666,8 +731,8 @@
 
     /**
      * Set the maximum number of elements we can store in a page.
-     * 
-     * @param btree The BTree to update
+     *
+     * @param btree The B-tree to update
      * @param pageSize The requested page size
      */
     /* no qualifier */static <K, V> void setPageSize( BTree<K, V> btree, int pageSize )
@@ -681,8 +746,8 @@
     //--------------------------------------------------------------------------------------------
     /**
      * Includes the intermediate nodes in the path up to and including the right most leaf of the tree
-     * 
-     * @param btree the btree
+     *
+     * @param btree the B-tree
      * @return a LinkedList of all the nodes and the final leaf
      */
     /* no qualifier*/static <K, V> LinkedList<ParentPos<K, V>> getPathToRightMostLeaf( BTree<K, V> btree )
@@ -724,50 +789,31 @@
 
 
     //--------------------------------------------------------------------------------------------
-    // Persisted BTree methods
+    // Persisted B-tree methods
     //--------------------------------------------------------------------------------------------
     /**
-     * Set the rootPage offset of the BTree
-     * 
-     * @param btree The btree to update
+     * Set the rootPage offset of the B-tree
+     *
+     * @param btree The B-tree to update
      * @param rootPageOffset The rootPageOffset to set
      */
     /* no qualifier*/static <K, V> void setRootPageOffset( BTree<K, V> btree, long rootPageOffset )
     {
         if ( btree instanceof PersistedBTree )
         {
-            ( ( PersistedBTree<K, V> ) btree ).setRootPageOffset( rootPageOffset );
+            ( ( PersistedBTree<K, V> ) btree ).getBtreeHeader().setRootPageOffset( rootPageOffset );
         }
         else
         {
-            throw new IllegalArgumentException( "The BTree must be a PersistedBTree" );
-        }
-    }
-
-
-    /**
-     * Set the nextBTree offset
-     * 
-     * @param btree The btree to update
-     * @param nextBTreeOffset The nextBTreeOffset to set
-     */
-    /* no qualifier*/static <K, V> void setNextBTreeOffset( BTree<K, V> btree, long nextBTreeOffset )
-    {
-        if ( btree instanceof PersistedBTree )
-        {
-            ( ( PersistedBTree<K, V> ) btree ).setNextBTreeOffset( nextBTreeOffset );
-        }
-        else
-        {
-            throw new IllegalArgumentException( "The BTree must be a PersistedBTree" );
+            throw new IllegalArgumentException( "The B-tree must be a PersistedBTree" );
         }
     }
 
 
     /**
      * Set the RecordManager
-     * 
-     * @param btree The btree to update
+     *
+     * @param btree The B-tree to update
      * @param recordManager The injected RecordManager
      */
     /* no qualifier*/static <K, V> void setRecordManager( BTree<K, V> btree, RecordManager recordManager )
@@ -778,15 +824,15 @@
         }
         else
         {
-            throw new IllegalArgumentException( "The BTree must be a PersistedBTree" );
+            throw new IllegalArgumentException( "The B-tree must be a PersistedBTree" );
         }
     }
 
 
     /**
      * Set the key at a give position
-     * 
-     * @param btree The btree to update
+     *
+     * @param btree The B-tree to update
      * @param page The page to update
      * @param pos The position of this key in the page
      * @param buffer The byte[] containing the serialized key
@@ -800,15 +846,15 @@
         }
         else
         {
-            throw new IllegalArgumentException( "The BTree must be a PersistedBTree" );
+            throw new IllegalArgumentException( "The B-tree must be a PersistedBTree" );
         }
     }
 
 
     /**
      * Includes the intermediate nodes in the path up to and including the left most leaf of the tree
-     * 
-     * @param btree The btree to process
+     *
+     * @param btree The B-tree to process
      * @return a LinkedList of all the nodes and the final leaf
      */
     /* no qualifier*/static <K, V> LinkedList<ParentPos<K, V>> getPathToLeftMostLeaf( BTree<K, V> btree )
@@ -850,7 +896,7 @@
         }
         else
         {
-            throw new IllegalArgumentException( "The BTree must be a PersistedBTree" );
+            throw new IllegalArgumentException( "The B-tree must be a PersistedBTree" );
         }
     }
 }
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java
index a6ec76d..2202551 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java
@@ -19,13 +19,12 @@
  */
 package org.apache.directory.mavibot.btree;
 
-
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicInteger;
 
 
 /**
- * Store in memory the information associated with a BTree. <br>
- * A BTree Header on disk contains the following elements :
+ * Store in memory the information associated with a B-tree. <br>
+ * A B-tree Header on disk contains the following elements :
  * <pre>
  * +--------------------+-------------+
  * | revision           | 8 bytes     |
@@ -34,55 +33,42 @@
  * +--------------------+-------------+
  * | rootPageOffset     | 8 bytes     |
  * +--------------------+-------------+
- * | nextBtreeHeader    | 8 bytes     |
- * +--------------------+-------------+
- * | pageSize           | 4 bytes     |
- * +--------------------+-------------+
- * | name               | 4 bytes + N |
- * +--------------------+-------------+
- * | keySerializeFQCN   | 4 bytes + N |
- * +--------------------+-------------+
- * | valueSerializeFQCN | 4 bytes + N |
+ * | BtreeOffset        | 8 bytes     |
  * +--------------------+-------------+
  * </pre>
- * Each BtreeHeader will be written starting on a new page.
+ * Each B-tree Header will be written starting on a new page.
+ * In memory, a B-tree Header store a bit more of information :
+ * <li>
+ * <ul>rootPage : the associated rootPage in memory</lu>
+ * <ul>nbUsers : the number of readThreads using this revision</lu>
+ * <ul>offset : the offset of this B-tre header</lu>
+ * </li>
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-/* No qualifier*/class BTreeHeader
+/* No qualifier*/class BTreeHeader<K, V> implements Cloneable
 {
     /** The current revision */
-    private AtomicLong revision = new AtomicLong( 0L );
+    private long revision = 0L;
 
-    /** The number of elements in this BTree */
-    private AtomicLong nbElems = new AtomicLong( 0L );
+    /** The number of elements in this B-tree */
+    private Long nbElems = 0L;
 
-    /** The offset of the BTree RootPage */
+    /** The offset of the B-tree RootPage */
     private long rootPageOffset;
 
-    /** The offset of the next BTree */
-    private long nextBTreeOffset;
-
-    /** The number of elements in a page for this BTree */
-    private int pageSize;
-
-    /** The BTree name */
-    private String name;
-
-    /** The FQCN of the Key serializer */
-    private String keySerializerFQCN;
-
-    /** The FQCN of the Value serializer */
-    private String valueSerializerFQCN;
+    /** The position of the B-tree header in the file */
+    private long btreeHeaderOffset;
 
     // Those are data which aren't serialized : they are in memory only */
-    /** The position in the file */
-    private long btreeOffset;
+    /** A Map containing the rootPage for this tree */
+    private Page<K, V> rootPage;
 
-    /** The existing versions */
-    private long[] versions;
+    /** The number of users for this BtreeHeader */
+    private AtomicInteger nbUsers = new AtomicInteger( 0 );
 
-    private int allowDuplicates = 0;
+    /** The B-tree this header is associated with */
+    private BTree<K, V> btree;
 
 
     /**
@@ -94,56 +80,61 @@
 
 
     /**
-     * @return the name
+     * @return the B-tree info Offset
      */
-    public String getName()
+    public long getBTreeInfoOffset()
     {
-        return name;
+        return ((PersistedBTree<K, V>)btree).getBtreeInfoOffset();
     }
 
 
     /**
-     * @param name the name to set
+     * @return the B-tree header Offset
      */
-    /* no qualifier */void setName( String name )
+    public long getBTreeHeaderOffset()
     {
-        this.name = name;
+        return btreeHeaderOffset;
+    }
+
+
+    public BTreeHeader<K, V> clone()
+    {
+        try
+        {
+            BTreeHeader<K, V> copy = (BTreeHeader<K, V>)super.clone();
+
+            return copy;
+        }
+        catch ( CloneNotSupportedException cnse )
+        {
+            return null;
+        }
     }
 
 
     /**
-     * @return the versions
+     * Copy the current B-tre header and return the copy
+     * @return
      */
-    public long[] getVersions()
+    /* no qualifier */ BTreeHeader<K, V> copy()
     {
-        return versions;
+        BTreeHeader<K, V> copy = clone();
+
+        // Clear the fields that should not be copied
+        copy.rootPage = null;
+        copy.rootPageOffset = -1L;
+        copy.btreeHeaderOffset = -1L;
+
+        return copy;
     }
 
 
     /**
-     * @param versions the versions to set
+     * @param btreeOffset the B-tree header Offset to set
      */
-    /* no qualifier */void setVersions( long[] versions )
+    /* no qualifier */void setBTreeHeaderOffset( long btreeHeaderOffset )
     {
-        this.versions = versions;
-    }
-
-
-    /**
-     * @return the btreeOffset
-     */
-    public long getBTreeOffset()
-    {
-        return btreeOffset;
-    }
-
-
-    /**
-     * @param btreeOffset the btreeOffset to set
-     */
-    /* no qualifier */void setBTreeOffset( long btreeOffset )
-    {
-        this.btreeOffset = btreeOffset;
+        this.btreeHeaderOffset = btreeHeaderOffset;
     }
 
 
@@ -170,7 +161,7 @@
      */
     public long getRevision()
     {
-        return revision.get();
+        return revision;
     }
 
 
@@ -179,18 +170,7 @@
      */
     /* no qualifier */void setRevision( long revision )
     {
-        this.revision.set( revision );
-    }
-
-
-    /**
-     * Increment the revision
-     *
-     * @return the new revision
-     */
-    /* no qualifier */long incrementRevision()
-    {
-        return revision.incrementAndGet();
+        this.revision = revision;
     }
 
 
@@ -199,25 +179,7 @@
      */
     public long getNbElems()
     {
-        return nbElems.get();
-    }
-
-
-    /**
-     * Increment the number of elements
-     */
-    /* no qualifier */void incrementNbElems()
-    {
-        nbElems.incrementAndGet();
-    }
-
-
-    /**
-     * Decrement the number of elements
-     */
-    public void decrementNbElems()
-    {
-        nbElems.decrementAndGet();
+        return nbElems;
     }
 
 
@@ -226,91 +188,89 @@
      */
     /* no qualifier */void setNbElems( long nbElems )
     {
-        this.nbElems.set( nbElems );
+        this.nbElems = nbElems;
     }
 
 
     /**
-     * @return the nextBTreeOffset
+     * Increment the number of elements
      */
-    public long getNextBTreeOffset()
+    /* no qualifier */void incrementNbElems()
     {
-        return nextBTreeOffset;
+        nbElems++;
     }
 
 
     /**
-     * @param nextBtreeOffset the nextBtreeOffset to set
+     * Decrement the number of elements
      */
-    /* no qualifier */void setNextBTreeOffset( long nextBTreeOffset )
+    /* no qualifier */void decrementNbElems()
     {
-        this.nextBTreeOffset = nextBTreeOffset;
+        nbElems--;
     }
 
 
     /**
-     * @return the pageSize
+     * @return the rootPage
      */
-    public int getPageSize()
+    /* no qualifier */ Page<K, V> getRootPage()
     {
-        return pageSize;
+        return rootPage;
     }
 
 
     /**
-     * @param pageSize the pageSize to set
+     * @param rootPage the rootPage to set
      */
-    /* no qualifier */void setPageSize( int pageSize )
+    /* no qualifier */ void setRootPage( Page<K, V> rootPage )
     {
-        this.pageSize = pageSize;
+        this.rootPage = rootPage;
+        this.rootPageOffset = ((AbstractPage<K, V>)rootPage).getOffset();
     }
 
 
     /**
-     * @return the keySerializerFQCN
+     * @return the nbUsers
      */
-    public String getKeySerializerFQCN()
+    /* no qualifier */ int getNbUsers()
     {
-        return keySerializerFQCN;
+        return nbUsers.get();
     }
 
 
     /**
-     * @param keySerializerFQCN the keySerializerFQCN to set
+     * Increment the number of users
      */
-    /* no qualifier */void setKeySerializerFQCN( String keySerializerFQCN )
+    /* no qualifier */ void incrementNbUsers()
     {
-        this.keySerializerFQCN = keySerializerFQCN;
+        nbUsers.incrementAndGet();
     }
 
 
     /**
-     * @return the valueSerializerFQCN
+     * Decrement the number of users
      */
-    public String getValueSerializerFQCN()
+    /* no qualifier */ void decrementNbUsers()
     {
-        return valueSerializerFQCN;
+        nbUsers.decrementAndGet();
     }
 
 
     /**
-     * @param valueSerializerFQCN the valueSerializerFQCN to set
+     * @return the btree
      */
-    /* no qualifier */void setValueSerializerFQCN( String valueSerializerFQCN )
+    /* no qualifier */ BTree<K, V> getBtree()
     {
-        this.valueSerializerFQCN = valueSerializerFQCN;
+        return btree;
     }
 
 
-    public boolean isAllowDuplicates()
+    /**
+     * @param btree the btree to set
+     */
+    /* no qualifier */ void setBtree( BTree<K, V> btree )
     {
-        return ( allowDuplicates == 1 );
-    }
-
-
-    /* no qualifier */void setAllowDuplicates( boolean allowDuplicates )
-    {
-        this.allowDuplicates = ( allowDuplicates ? 1 : 0 );
+        this.btree = btree;
     }
 
 
@@ -321,42 +281,14 @@
     {
         StringBuilder sb = new StringBuilder();
 
-        sb.append( "Btree '" ).append( name ).append( "'" );
+        sb.append( "B-treeHeader " );
+        sb.append( ", offset[0x" ).append( Long.toHexString( btreeHeaderOffset ) ).append( "]" );
+        sb.append( ", name[" ).append( btree.getName() ).append( "]" );
         sb.append( ", revision[" ).append( revision ).append( "]" );
-        sb.append( ", btreeOffset[" ).append( btreeOffset ).append( "]" );
-        sb.append( ", rootPageOffset[" ).append( rootPageOffset ).append( "]" );
-        sb.append( ", nextBTree[" ).append( nextBTreeOffset ).append( "]" );
+        sb.append( ", btreeInfoOffset[0x" ).append( Long.toHexString( ((PersistedBTree<K, V>)btree).getBtreeInfoOffset() ) ).append( "]" );
+        sb.append( ", rootPageOffset[0x" ).append( Long.toHexString( rootPageOffset ) ).append( "]" );
         sb.append( ", nbElems[" ).append( nbElems ).append( "]" );
-        sb.append( ", pageSize[" ).append( pageSize ).append( "]" );
-        sb.append( ", hasDuplicates[" ).append( isAllowDuplicates() ).append( "]" );
-        sb.append( "{\n" );
-        sb.append( "    Key serializer   : " ).append( keySerializerFQCN ).append( "\n" );
-        sb.append( "    Value serializer : " ).append( valueSerializerFQCN ).append( "\n" );
-        sb.append( "}\n" );
-
-        if ( ( versions != null ) && ( versions.length != 0 ) )
-        {
-            sb.append( "Versions : \n" );
-            sb.append( "{\n" );
-
-            boolean isFirst = true;
-
-            for ( long version : versions )
-            {
-                if ( isFirst )
-                {
-                    isFirst = false;
-                }
-                else
-                {
-                    sb.append( ",\n" );
-                }
-
-                sb.append( "    " ).append( version );
-            }
-
-            sb.append( "}\n" );
-        }
+        sb.append( ", nbUsers[" ).append( nbUsers.get() ).append( "]" );
 
         return sb.toString();
     }
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java
index ffa6fbe..0a2db9c 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java
@@ -21,24 +21,35 @@
 
 
 /**
- * An enum to describe the BTree type. We have three possible type :
+ * An enum to describe the B-tree type. We have three possible type :
  * <ul>
- * <li>IN_MEMORY : the BTree will remain in memory, and won't be persisted on disk</li>
- * <li>PERSISTENT : the BTree is in memory, but will be persisted on disk</li>
- * <li>MANAGED : the BTree is managed by a RecordManager, and some pages may
+ * <li>IN_MEMORY : the B-tree will remain in memory, and won't be persisted on disk</li>
+ * <li>BACKED_ON_DISK : the B-tree is in memory, but will be persisted on disk</li>
+ * <li>PERSISTED : the B-tree is managed by a RecordManager, and some pages may
  * be swapped out from memory on demand</li>
+ * <li>PERSISTED_SUB : The B-tree is a Persisted B-tree, but a Sub B-tree one</li>
+ * <li>PERSISTED_MANAGEMENT : This is a Persisted B-tree used to manage the other B-trees</li>
  * </ul>
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public enum BTreeTypeEnum
 {
-    /** Pure in-memory BTree, not persisted on disk */
+    /** Pure in-memory B-tree, not persisted on disk */
     IN_MEMORY,
 
-    /** Persisted BTree */
+    /** Persisted B-tree */
     PERSISTED,
 
-    /** In-memory BTree but saved on disk */
+    /** Persisted sub B-tree */
+    PERSISTED_SUB,
+
+    /** Persisted Management B-tree */
+    BTREE_OF_BTREES,
+
+    /** Persisted Management B-tree */
+    COPIED_PAGES_BTREE,
+
+    /** In-memory B-tree but saved on disk */
     BACKED_ON_DISK
 }
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/EmptyTupleCursor.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/EmptyTupleCursor.java
new file mode 100644
index 0000000..4afefb2
--- /dev/null
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/EmptyTupleCursor.java
@@ -0,0 +1,234 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree;
+
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
+
+
+/**
+ * A Cursor which is used when we have no element to return
+ * <p>
+ *
+ * @param <K> The type for the Key
+ * @param <V> The type for the stored value
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class EmptyTupleCursor<K, V> extends TupleCursor<K, V>
+{
+    private long revision;
+    private long creationDate;
+
+    /**
+     * Creates a new instance of Cursor, starting on a page at a given position.
+     *
+     * @param transaction The transaction this operation is protected by
+     * @param stack The stack of parent's from root to this page
+     */
+    public EmptyTupleCursor( long revision )
+    {
+        super();
+
+        this.revision = revision;
+        creationDate = System.currentTimeMillis();
+    }
+
+
+    /**
+     * Change the position in the current cursor to set it after the last key
+     */
+    public void afterLast() throws IOException
+    {
+    }
+
+
+    /**
+     * Change the position in the current cursor before the first key
+     */
+    public void beforeFirst() throws IOException
+    {
+    }
+
+
+    /**
+     * Tells if the cursor can return a next element
+     *
+     * @return true if there are some more elements
+     * @throws IOException
+     * @throws EndOfFileExceededException
+     */
+    public boolean hasNext() throws EndOfFileExceededException, IOException
+    {
+        return false;
+    }
+
+
+    /**
+     * Find the next key/value
+     *
+     * @return A Tuple containing the found key and value
+     * @throws IOException
+     * @throws EndOfFileExceededException
+     */
+    public Tuple<K, V> next() throws EndOfFileExceededException, IOException
+    {
+        throw new NoSuchElementException( "No tuple present" );
+    }
+
+
+    /**
+     * Get the next non-duplicate key.
+     * If the BTree contains :
+     *
+     *  <ul>
+     *    <li><1,0></li>
+     *    <li><1,1></li>
+     *    <li><1,2></li>
+     *    <li><2,0></li>
+     *    <li><2,1></li>
+     *  </ul>
+     *
+     *  and cursor is present at <1,1> then the returned tuple will be <2,0> (not <1,2>)
+     *
+     * @return A Tuple containing the found key and value
+     * @throws EndOfFileExceededException
+     * @throws IOException
+     */
+    public Tuple<K, V> nextKey() throws EndOfFileExceededException, IOException
+    {
+        // This is the end : no more value
+        throw new NoSuchElementException( "No more tuples present" );
+    }
+
+
+    /**
+     * Tells if the cursor can return a next key
+     *
+     * @return true if there are some more keys
+     * @throws IOException
+     * @throws EndOfFileExceededException
+     */
+    public boolean hasNextKey() throws EndOfFileExceededException, IOException
+    {
+        return false;
+    }
+
+
+    /**
+     * Tells if the cursor can return a previous element
+     *
+     * @return true if there are some more elements
+     * @throws IOException
+     * @throws EndOfFileExceededException
+     */
+    public boolean hasPrev() throws EndOfFileExceededException, IOException
+    {
+        return false;
+    }
+
+
+    /**
+     * Find the previous key/value
+     *
+     * @return A Tuple containing the found key and value
+     * @throws IOException
+     * @throws EndOfFileExceededException
+     */
+    public Tuple<K, V> prev() throws EndOfFileExceededException, IOException
+    {
+        throw new NoSuchElementException( "No more tuple present" );
+    }
+
+
+    /**
+     * Get the previous non-duplicate key.
+     * If the BTree contains :
+     *
+     *  <ul>
+     *    <li><1,0></li>
+     *    <li><1,1></li>
+     *    <li><1,2></li>
+     *    <li><2,0></li>
+     *    <li><2,1></li>
+     *  </ul>
+     *
+     *  and cursor is present at <2,1> then the returned tuple will be <1,0> (not <2,0>)
+     *
+     * @return A Tuple containing the found key and value
+     * @throws EndOfFileExceededException
+     * @throws IOException
+     */
+    public Tuple<K, V> prevKey() throws EndOfFileExceededException, IOException
+    {
+        throw new NoSuchElementException( "No more tuples present" );
+    }
+
+
+    /**
+     * Tells if the cursor can return a previous key
+     *
+     * @return true if there are some more keys
+     * @throws IOException
+     * @throws EndOfFileExceededException
+     */
+    public boolean hasPrevKey() throws EndOfFileExceededException, IOException
+    {
+        return false;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void close()
+    {
+    }
+
+
+    /**
+     * Get the creation date
+     * @return The creation date for this cursor
+     */
+    public long getCreationDate()
+    {
+        return creationDate;
+    }
+
+
+    /**
+     * Get the current revision
+     *
+     * @return The revision this cursor is based on
+     */
+    public long getRevision()
+    {
+        return revision;
+    }
+
+
+    public String toString()
+    {
+        return "EmptyTupleCursor";
+    }
+}
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/EmptyValueCursor.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/EmptyValueCursor.java
new file mode 100644
index 0000000..f38e7a4
--- /dev/null
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/EmptyValueCursor.java
@@ -0,0 +1,188 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree;
+
+
+import java.io.IOException;
+
+import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
+
+
+/**
+ * A Cursor which is used when we have no value to return
+ * <p>
+ *
+ * @param <K> The type for the Key
+ * @param <V> The type for the stored value
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class EmptyValueCursor<V> implements ValueCursor<V>
+{
+    private long revision;
+    private long creationDate;
+
+    /**
+     * Creates a new instance of Cursor, starting on a page at a given position.
+     *
+     * @param transaction The transaction this operation is protected by
+     * @param stack The stack of parent's from root to this page
+     */
+    public EmptyValueCursor( long revision )
+    {
+        super();
+
+        this.revision = revision;
+        creationDate = System.currentTimeMillis();
+    }
+
+
+    /**
+     * Change the position in the current cursor to set it after the last key
+     */
+    public void afterLast() throws IOException
+    {
+    }
+
+
+    /**
+     * Change the position in the current cursor before the first key
+     */
+    public void beforeFirst() throws IOException
+    {
+    }
+
+
+    /**
+     * Tells if the cursor can return a next element
+     *
+     * @return true if there are some more elements
+     * @throws IOException
+     * @throws EndOfFileExceededException
+     */
+    public boolean hasNext() throws EndOfFileExceededException, IOException
+    {
+        return false;
+    }
+
+
+    /**
+     * Tells if the cursor can return a next key
+     *
+     * @return true if there are some more keys
+     * @throws IOException
+     * @throws EndOfFileExceededException
+     */
+    public boolean hasNextKey() throws EndOfFileExceededException, IOException
+    {
+        return false;
+    }
+
+
+    /**
+     * Tells if the cursor can return a previous element
+     *
+     * @return true if there are some more elements
+     * @throws IOException
+     * @throws EndOfFileExceededException
+     */
+    public boolean hasPrev() throws EndOfFileExceededException, IOException
+    {
+        return false;
+    }
+
+
+    /**
+     * Tells if the cursor can return a previous key
+     *
+     * @return true if there are some more keys
+     * @throws IOException
+     * @throws EndOfFileExceededException
+     */
+    public boolean hasPrevKey() throws EndOfFileExceededException, IOException
+    {
+        return false;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public V prev() throws EndOfFileExceededException, IOException
+    {
+        return null;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public V next() throws EndOfFileExceededException, IOException
+    {
+        return null;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void close()
+    {
+    }
+
+
+    /**
+     * Get the creation date
+     * @return The creation date for this cursor
+     */
+    public long getCreationDate()
+    {
+        return creationDate;
+    }
+
+
+    /**
+     * Get the current revision
+     *
+     * @return The revision this cursor is based on
+     */
+    public long getRevision()
+    {
+        return revision;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int size()
+    {
+        return 0;
+    }
+
+
+    public String toString()
+    {
+        return "EmptyValueCursor";
+    }
+}
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryBTree.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryBTree.java
index 0be326c..fb09eac 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryBTree.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryBTree.java
@@ -29,7 +29,6 @@
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.directory.mavibot.btree.exception.InitializationException;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
@@ -72,18 +71,18 @@
     /** The associated journal. If null, this is an in-memory btree  */
     private File journal;
 
+    /** The directory where the journal will be stored */
     private File envDir;
 
+    /** The Journal channel */
     private FileChannel journalChannel = null;
 
-
     /**
      * Creates a new BTree, with no initialization.
      */
     /* no qualifier */InMemoryBTree()
     {
         super();
-        btreeHeader = new BTreeHeader();
         setType( BTreeTypeEnum.IN_MEMORY );
     }
 
@@ -97,9 +96,9 @@
     /* no qualifier */InMemoryBTree( InMemoryBTreeConfiguration<K, V> configuration )
     {
         super();
-        String name = configuration.getName();
+        String btreeName = configuration.getName();
 
-        if ( name == null )
+        if ( btreeName == null )
         {
             throw new IllegalArgumentException( "BTree name cannot be null" );
         }
@@ -111,29 +110,35 @@
             envDir = new File( filePath );
         }
 
-        btreeHeader = new BTreeHeader();
-        btreeHeader.setName( name );
-        btreeHeader.setPageSize( configuration.getPageSize() );
-
-        keySerializer = configuration.getKeySerializer();
-        btreeHeader.setKeySerializerFQCN( keySerializer.getClass().getName() );
-
-        valueSerializer = configuration.getValueSerializer();
-        btreeHeader.setValueSerializerFQCN( valueSerializer.getClass().getName() );
+        // Store the configuration in the B-tree
+        setName( btreeName );
+        setPageSize( configuration.getPageSize() );
+        setKeySerializer( configuration.getKeySerializer() );
+        setValueSerializer( configuration.getValueSerializer() );
+        setAllowDuplicates( configuration.isAllowDuplicates() );
+        setType( configuration.getType() );
 
         readTimeOut = configuration.getReadTimeOut();
         writeBufferSize = configuration.getWriteBufferSize();
-        btreeHeader.setAllowDuplicates( configuration.isAllowDuplicates() );
-        setType( configuration.getType() );
 
         if ( keySerializer.getComparator() == null )
         {
             throw new IllegalArgumentException( "Comparator should not be null" );
         }
 
+        // Create the B-tree header
+        BTreeHeader<K, V> newBtreeHeader = new BTreeHeader<K, V>();
+
         // Create the first root page, with revision 0L. It will be empty
         // and increment the revision at the same time
-        rootPage = new InMemoryLeaf<K, V>( this );
+        newBtreeHeader.setBTreeHeaderOffset( 0L );
+        newBtreeHeader.setRevision( 0L );
+        newBtreeHeader.setNbElems( 0L );
+        newBtreeHeader.setRootPage( new InMemoryLeaf<K, V>( this ) );
+        newBtreeHeader.setRootPageOffset( 0L );
+
+        btreeRevisions.put( 0L,  newBtreeHeader );
+        currentBtreeHeader = newBtreeHeader;
 
         // Now, initialize the BTree
         try
@@ -152,7 +157,7 @@
      *
      * @throws IOException If we get some exception while initializing the BTree
      */
-    public void init() throws IOException
+    private void init() throws IOException
     {
         // if not in-memory then default to persist mode instead of managed
         if ( envDir != null )
@@ -160,13 +165,14 @@
             if ( !envDir.exists() )
             {
                 boolean created = envDir.mkdirs();
+
                 if ( !created )
                 {
                     throw new IllegalStateException( "Could not create the directory " + envDir + " for storing data" );
                 }
             }
 
-            this.file = new File( envDir, btreeHeader.getName() + DATA_SUFFIX );
+            this.file = new File( envDir, getName() + DATA_SUFFIX );
 
             this.journal = new File( envDir, file.getName() + JOURNAL_SUFFIX );
             setType( BTreeTypeEnum.BACKED_ON_DISK );
@@ -174,8 +180,9 @@
 
         // Create the queue containing the pending read transactions
         readTransactions = new ConcurrentLinkedQueue<ReadTransaction<K, V>>();
-
-        writeLock = new ReentrantLock();
+        
+        // Create the transaction manager
+        transactionManager = new InMemoryTransactionManager();
 
         // Check the files and create them if missing
         // Create the queue containing the modifications, if it's not a in-memory btree
@@ -202,6 +209,12 @@
         else
         {
             setType( BTreeTypeEnum.IN_MEMORY );
+
+            // This is a new Btree, we have to store the BtreeHeader
+            BTreeHeader<K, V> btreeHeader = new BTreeHeader<K, V>();
+            btreeHeader.setRootPage( new InMemoryLeaf<K, V>( this ) );
+            btreeHeader.setBtree( this );
+            storeRevision( btreeHeader );
         }
 
         // Initialize the txnManager thread
@@ -211,6 +224,43 @@
 
 
     /**
+     * {@inheritDoc}
+     */
+    protected ReadTransaction<K, V> beginReadTransaction()
+    {
+        BTreeHeader<K, V> btreeHeader = getBtreeHeader();
+
+        ReadTransaction<K, V> readTransaction = new ReadTransaction<K, V>( btreeHeader, readTransactions );
+
+        readTransactions.add( readTransaction );
+
+        return readTransaction;
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    protected ReadTransaction<K, V> beginReadTransaction( long revision )
+    {
+        BTreeHeader<K, V> btreeHeader = getBtreeHeader( revision );
+
+        if ( btreeHeader != null )
+        {
+            ReadTransaction<K, V> readTransaction = new ReadTransaction<K, V>(  btreeHeader, readTransactions );
+
+            readTransactions.add( readTransaction );
+
+            return readTransaction;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
      * Close the BTree, cleaning up all the data structure
      */
     public void close() throws IOException
@@ -225,8 +275,6 @@
             flush();
             journalChannel.close();
         }
-
-        rootPage = null;
     }
 
 
@@ -244,59 +292,65 @@
      */
     protected Tuple<K, V> delete( K key, V value, long revision ) throws IOException
     {
-        writeLock.lock();
-
-        try
+        if ( revision == -1L )
         {
-            // If the key exists, the existing value will be replaced. We store it
-            // to return it to the caller.
-            Tuple<K, V> tuple = null;
-
-            // Try to delete the entry starting from the root page. Here, the root
-            // page may be either a Node or a Leaf
-            DeleteResult<K, V> result = rootPage.delete( revision, key, value, null, -1 );
-
-            if ( result instanceof NotPresentResult )
-            {
-                // Key not found.
-                return null;
-            }
-
-            // Keep the oldRootPage so that we can later access it
-            Page<K, V> oldRootPage = rootPage;
-
-            if ( result instanceof RemoveResult )
-            {
-                // The element was found, and removed
-                RemoveResult<K, V> removeResult = ( RemoveResult<K, V> ) result;
-
-                Page<K, V> modifiedPage = removeResult.getModifiedPage();
-
-                // This is a new root
-                rootPage = modifiedPage;
-                tuple = removeResult.getRemovedElement();
-            }
-
-            if ( withJournal )
-            {
-                // Inject the modification into the modification queue
-                writeToJournal( new Deletion<K, V>( key ) );
-            }
-
-            // Decrease the number of elements in the current tree if the deletion is successful
-            if ( tuple != null )
-            {
-                btreeHeader.decrementNbElems();
-            }
-
-            // Return the value we have found if it was modified
-            return tuple;
+            revision = currentRevision.get() + 1;
         }
-        finally
+
+        BTreeHeader<K, V> oldBtreeHeader = getBtreeHeader();
+        BTreeHeader<K, V> newBtreeHeader = createNewBtreeHeader( oldBtreeHeader, revision );
+        newBtreeHeader.setBtree( this );
+
+        // If the key exists, the existing value will be replaced. We store it
+        // to return it to the caller.
+        Tuple<K, V> tuple = null;
+
+        // Try to delete the entry starting from the root page. Here, the root
+        // page may be either a Node or a Leaf
+        DeleteResult<K, V> result = getRootPage().delete( key, value, revision );
+
+        if ( result instanceof NotPresentResult )
         {
-            // See above
-            writeLock.unlock();
+            // Key not found.
+            return null;
         }
+
+        // Keep the oldRootPage so that we can later access it
+        //Page<K, V> oldRootPage = rootPage;
+
+        if ( result instanceof RemoveResult )
+        {
+            // The element was found, and removed
+            RemoveResult<K, V> removeResult = ( RemoveResult<K, V> ) result;
+
+            Page<K, V> modifiedPage = removeResult.getModifiedPage();
+
+            // This is a new root
+            newBtreeHeader.setRootPage( modifiedPage );
+            tuple = removeResult.getRemovedElement();
+        }
+
+        if ( withJournal )
+        {
+            // Inject the modification into the modification queue
+            writeToJournal( new Deletion<K, V>( key ) );
+        }
+
+        // Decrease the number of elements in the current tree if the deletion is successful
+        if ( tuple != null )
+        {
+            newBtreeHeader.decrementNbElems();
+        }
+
+        storeRevision( newBtreeHeader );
+
+        // Return the value we have found if it was modified
+        if ( oldBtreeHeader.getNbUsers() == 0 )
+        {
+            btreeRevisions.remove( oldBtreeHeader.getRevision() );
+        }
+
+        return tuple;
     }
 
 
@@ -315,11 +369,17 @@
      */
     /* no qualifier */InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
     {
-        if ( key == null )
+        // We have to start a new transaction, which will be committed or rollbacked
+        // locally. This will duplicate the current BtreeHeader during this phase.
+        if ( revision == -1L )
         {
-            throw new IllegalArgumentException( "Key must not be null" );
+            revision = currentRevision.get() + 1;
         }
 
+        BTreeHeader<K, V> oldBtreeHeader = getBtreeHeader();
+        BTreeHeader<K, V> newBtreeHeader = createNewBtreeHeader( oldBtreeHeader, revision );
+        newBtreeHeader.setBtree( this );
+
         // If the key exists, the existing value will be replaced. We store it
         // to return it to the caller.
         V modifiedValue = null;
@@ -327,7 +387,7 @@
         // Try to insert the new value in the tree at the right place,
         // starting from the root page. Here, the root page may be either
         // a Node or a Leaf
-        InsertResult<K, V> result = rootPage.insert( revision, key, value );
+        InsertResult<K, V> result = newBtreeHeader.getRootPage().insert( key, value, revision );
 
         if ( result instanceof ModifyResult )
         {
@@ -337,7 +397,7 @@
 
             // The root has just been modified, we haven't split it
             // Get it and make it the current root page
-            rootPage = modifiedPage;
+            newBtreeHeader.setRootPage( modifiedPage );
 
             modifiedValue = modifyResult.getModifiedValue();
         }
@@ -350,12 +410,9 @@
             K pivot = splitResult.getPivot();
             Page<K, V> leftPage = splitResult.getLeftPage();
             Page<K, V> rightPage = splitResult.getRightPage();
-            Page<K, V> newRootPage = null;
 
             // Create the new rootPage
-            newRootPage = new InMemoryNode<K, V>( this, revision, pivot, leftPage, rightPage );
-
-            rootPage = newRootPage;
+            newBtreeHeader.setRootPage( new InMemoryNode<K, V>( this, revision, pivot, leftPage, rightPage ) );
         }
 
         // Inject the modification into the modification queue
@@ -368,7 +425,19 @@
         // and does not replace an element
         if ( modifiedValue == null )
         {
-            btreeHeader.incrementNbElems();
+            newBtreeHeader.incrementNbElems();
+        }
+
+        storeRevision( newBtreeHeader );
+
+        if ( oldBtreeHeader.getNbUsers() == 0 )
+        {
+            long oldRevision = oldBtreeHeader.getRevision();
+
+            if ( oldRevision < newBtreeHeader.getRevision() )
+            {
+                btreeRevisions.remove( oldBtreeHeader.getRevision() );
+            }
         }
 
         // Return the value we have found if it was modified
@@ -443,45 +512,53 @@
         // Create a buffer containing 200 4Kb pages (around 1Mb)
         ByteBuffer bb = ByteBuffer.allocateDirect( writeBufferSize );
 
-        TupleCursor<K, V> cursor = browse();
-
-        if ( keySerializer == null )
+        try
         {
-            throw new MissingSerializerException( "Cannot flush the btree without a Key serializer" );
+            TupleCursor<K, V> cursor = browse();
+    
+            if ( keySerializer == null )
+            {
+                throw new MissingSerializerException( "Cannot flush the btree without a Key serializer" );
+            }
+    
+            if ( valueSerializer == null )
+            {
+                throw new MissingSerializerException( "Cannot flush the btree without a Value serializer" );
+            }
+    
+            // Write the number of elements first
+            bb.putLong( getBtreeHeader().getNbElems() );
+    
+            while ( cursor.hasNext() )
+            {
+                Tuple<K, V> tuple = cursor.next();
+    
+                byte[] keyBuffer = keySerializer.serialize( tuple.getKey() );
+    
+                writeBuffer( ch, bb, keyBuffer );
+    
+                byte[] valueBuffer = valueSerializer.serialize( tuple.getValue() );
+    
+                writeBuffer( ch, bb, valueBuffer );
+            }
+    
+            // Write the buffer if needed
+            if ( bb.position() > 0 )
+            {
+                bb.flip();
+                ch.write( bb );
+            }
+    
+            // Flush to the disk for real
+            ch.force( true );
+            ch.close();
         }
-
-        if ( valueSerializer == null )
+        catch ( KeyNotFoundException knfe )
         {
-            throw new MissingSerializerException( "Cannot flush the btree without a Value serializer" );
+            knfe.printStackTrace();
+            throw new IOException( knfe.getMessage() );
         }
 
-        // Write the number of elements first
-        bb.putLong( btreeHeader.getNbElems() );
-
-        while ( cursor.hasNext() )
-        {
-            Tuple<K, V> tuple = cursor.next();
-
-            byte[] keyBuffer = keySerializer.serialize( tuple.getKey() );
-
-            writeBuffer( ch, bb, keyBuffer );
-
-            byte[] valueBuffer = valueSerializer.serialize( tuple.getValue() );
-
-            writeBuffer( ch, bb, valueBuffer );
-        }
-
-        // Write the buffer if needed
-        if ( bb.position() > 0 )
-        {
-            bb.flip();
-            ch.write( bb );
-        }
-
-        // Flush to the disk for real
-        ch.force( true );
-        ch.close();
-
         // Rename the current file to save a backup
         File backupFile = File.createTempFile( "mavibot", null, baseDirectory );
         file.renameTo( backupFile );
@@ -501,8 +578,6 @@
      */
     private void applyJournal() throws IOException
     {
-        long revision = generateRevision();
-
         if ( !journal.exists() )
         {
             throw new IOException( "The journal does not exist" );
@@ -535,7 +610,7 @@
                     //values.add( value );
 
                     // Inject the data in the tree. (to be replaced by a bulk load)
-                    insert( key, value, revision );
+                    insert( key, value, getBtreeHeader().getRevision() );
                 }
                 else
                 {
@@ -543,7 +618,7 @@
                     K key = keySerializer.deserialize( bufferHandler );
 
                     // Remove the key from the tree
-                    delete( key, revision );
+                    delete( key, getBtreeHeader().getRevision() );
                 }
             }
         }
@@ -565,8 +640,6 @@
      */
     public void load( File file ) throws IOException
     {
-        long revision = generateRevision();
-
         if ( !file.exists() )
         {
             throw new IOException( "The file does not exist" );
@@ -579,11 +652,6 @@
         BufferHandler bufferHandler = new BufferHandler( channel, buffer );
 
         long nbElems = LongSerializer.deserialize( bufferHandler.read( 8 ) );
-        btreeHeader.setNbElems( nbElems );
-
-        // Prepare a list of keys and values read from the disk
-        //List<K> keys = new ArrayList<K>();
-        //List<V> values = new ArrayList<V>();
 
         // desactivate the journal while we load the file
         boolean isJournalActivated = withJournal;
@@ -596,15 +664,11 @@
             // Read the key
             K key = keySerializer.deserialize( bufferHandler );
 
-            //keys.add( key );
-
             // Read the value
             V value = valueSerializer.deserialize( bufferHandler );
 
-            //values.add( value );
-
             // Inject the data in the tree. (to be replaced by a bulk load)
-            insert( key, value, revision );
+            insert( key, value, getBtreeHeader().getRevision() );
         }
 
         // Restore the withJournal value
@@ -616,7 +680,7 @@
 
 
     /**
-     * Get the rootPzge associated to a give revision.
+     * Get the rootPage associated to a give revision.
      *
      * @param revision The revision we are looking for
      * @return The rootPage associated to this revision
@@ -626,7 +690,24 @@
     public Page<K, V> getRootPage( long revision ) throws IOException, KeyNotFoundException
     {
         // Atm, the in-memory BTree does not support searches in many revisions
-        return rootPage;
+        return getBtreeHeader().getRootPage();
+    }
+
+
+    /**
+     * Get the current rootPage
+     *
+     * @return The rootPage
+     */
+    public Page<K, V> getRootPage()
+    {
+        return getBtreeHeader().getRootPage();
+    }
+
+
+    /* no qualifier */void setRootPage( Page<K, V> root )
+    {
+        getBtreeHeader().setRootPage( root );
     }
 
 
@@ -718,29 +799,19 @@
 
 
     /**
-     * Starts a transaction
+     * Create a new B-tree header to be used for update operations
+     * @param revision The reclaimed revision
      */
-    public void beginTransaction()
+    private BTreeHeader<K, V> createNewBtreeHeader( BTreeHeader<K, V> btreeHeader, long revision )
     {
-        // Does nothing...
-    }
+        BTreeHeader<K, V> newBtreeHeader = new BTreeHeader<K, V>();
 
+        newBtreeHeader.setBTreeHeaderOffset( btreeHeader.getBTreeHeaderOffset() );
+        newBtreeHeader.setRevision( revision );
+        newBtreeHeader.setNbElems( btreeHeader.getNbElems() );
+        newBtreeHeader.setRootPage( btreeHeader.getRootPage() );
 
-    /**
-     * Commits a transaction
-     */
-    public void commit()
-    {
-        // Does nothing...
-    }
-
-
-    /**
-     * Rollback a transaction
-     */
-    public void rollback()
-    {
-        // Does nothing...
+        return newBtreeHeader;
     }
 
 
@@ -760,16 +831,19 @@
             case BACKED_ON_DISK:
                 sb.append( "Persistent " );
                 break;
-
+                
+            default :
+                sb.append( "Wrong type... " );
+                break;
         }
 
         sb.append( "BTree" );
-        sb.append( "[" ).append( btreeHeader.getName() ).append( "]" );
-        sb.append( "( pageSize:" ).append( btreeHeader.getPageSize() );
+        sb.append( "[" ).append( getName() ).append( "]" );
+        sb.append( "( pageSize:" ).append( getPageSize() );
 
-        if ( rootPage != null )
+        if ( getBtreeHeader().getRootPage() != null )
         {
-            sb.append( ", nbEntries:" ).append( btreeHeader.getNbElems() );
+            sb.append( ", nbEntries:" ).append( getBtreeHeader().getNbElems() );
         }
         else
         {
@@ -787,7 +861,7 @@
             sb.append( keySerializer.getComparator().getClass().getSimpleName() );
         }
 
-        sb.append( ", DuplicatesAllowed: " ).append( btreeHeader.isAllowDuplicates() );
+        sb.append( ", DuplicatesAllowed: " ).append( isAllowDuplicates() );
 
         if ( getType() == BTreeTypeEnum.BACKED_ON_DISK )
         {
@@ -822,7 +896,7 @@
         }
 
         sb.append( ") : \n" );
-        sb.append( rootPage.dumpPage( "" ) );
+        sb.append( getRootPage().dumpPage( "" ) );
 
         return sb.toString();
     }
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryLeaf.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryLeaf.java
index e9a8660..2aab808 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryLeaf.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryLeaf.java
@@ -27,7 +27,6 @@
 import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 
-
 /**
  * A MVCC Leaf. It stores the keys and values. It does not have any children.
  *
@@ -72,7 +71,7 @@
     /**
      * {@inheritDoc}
      */
-    public InsertResult<K, V> insert( long revision, K key, V value ) throws IOException
+    public InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
     {
         // Find the key into this leaf
         int pos = findPos( key );
@@ -117,7 +116,7 @@
      * {@inheritDoc}
      */
     @SuppressWarnings("unchecked")
-    public DeleteResult<K, V> delete( long revision, K key, V value, Page<K, V> parent, int parentPos )
+    /* no qualifier */ DeleteResult<K, V> delete( K key, V value, long revision, Page<K, V> parent, int parentPos )
         throws IOException
     {
         // Check that the leaf is not empty
@@ -486,7 +485,7 @@
         }
         else
         {
-            throw KEY_NOT_FOUND_EXCEPTION;
+            throw KeyNotFoundException.INSTANCE;
         }
     }
 
@@ -512,7 +511,7 @@
         }
         else
         {
-            throw KEY_NOT_FOUND_EXCEPTION;
+            throw KeyNotFoundException.INSTANCE;
         }
     }
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryNode.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryNode.java
index fa0e59f..4f5d681 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryNode.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryNode.java
@@ -28,7 +28,7 @@
 /**
  * A MVCC Node. It stores the keys and references to its children page. It does not
  * contain any value.
- * 
+ *
  * @param <K> The type for the Key
  * @param <V> The type for the stored value
  *
@@ -40,7 +40,7 @@
      * Creates a new Node which will contain only one key, with references to
      * a left and right page. This is a specific constructor used by the btree
      * when the root was full when we added a new value.
-     * 
+     *
      * @param btree the parent BTree
      * @param revision the Node revision
      * @param nbElems The number of elements in this Node
@@ -59,7 +59,7 @@
      * Creates a new Node which will contain only one key, with references to
      * a left and right page. This is a specific constructor used by the btree
      * when the root was full when we added a new value.
-     * 
+     *
      * @param btree the parent BTree
      * @param revision the Node revision
      * @param key The new key
@@ -89,7 +89,7 @@
     /**
      * {@inheritDoc}
      */
-    public InsertResult<K, V> insert( long revision, K key, V value ) throws IOException
+    public InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
     {
         // Find the key into this leaf
         int pos = findPos( key );
@@ -105,7 +105,7 @@
         Page<K, V> child = children[pos].getValue();
 
         // and insert the <K, V> into this child
-        InsertResult<K, V> result = child.insert( revision, key, value );
+        InsertResult<K, V> result = child.insert( key, value, revision );
 
         // Ok, now, we have injected the <K, V> tuple down the tree. Let's check
         // the result to see if we have to split the current page
@@ -145,7 +145,7 @@
     /**
      * Modifies the current node after a remove has been done in one of its children.
      * The node won't be merged with another node.
-     * 
+     *
      * @param removeResult The result of a remove operation
      * @param index the position of the key, not transformed
      * @param pos The position of the key, as a positive value
@@ -188,7 +188,7 @@
     /**
      * Handles the removal of an element from the root page, when two of its children
      * have been merged.
-     * 
+     *
      * @param mergedResult The merge result
      * @param pos The position in the current root
      * @param found Tells if the removed key is present in the root page
@@ -223,7 +223,7 @@
      * Borrows an element from the right sibling, creating a new sibling with one
      * less element and creating a new page where the element to remove has been
      * deleted and the borrowed element added on the right.
-     * 
+     *
      * @param revision The new revision for all the pages
      * @param sibling The right sibling
      * @param pos The position of the element to remove
@@ -308,7 +308,7 @@
      * Borrows an element from the left sibling, creating a new sibling with one
      * less element and creating a new page where the element to remove has been
      * deleted and the borrowed element added on the left.
-     * 
+     *
      * @param revision The new revision for all the pages
      * @param sibling The left sibling
      * @param pos The position of the element to remove
@@ -392,7 +392,7 @@
     /**
      * We have to merge the node with its sibling, both have N/2 elements before the element
      * removal.
-     * 
+     *
      * @param revision The revision
      * @param mergedResult The result of the merge
      * @param sibling The Page we will merge the current page with
@@ -523,7 +523,7 @@
     /**
      * {@inheritDoc}
      */
-    public DeleteResult<K, V> delete( long revision, K key, V value, Page<K, V> parent, int parentPos )
+    /* no qualifier */ DeleteResult<K, V> delete( K key, V value, long revision, Page<K, V> parent, int parentPos )
         throws IOException
     {
         // We first try to delete the element from the child it belongs to
@@ -538,12 +538,12 @@
         {
             index = -( pos + 1 );
             child = children[-pos].getValue();
-            deleteResult = child.delete( revision, key, value, this, -pos );
+            deleteResult = ((AbstractPage<K, V>)child).delete( key, value, revision, this, -pos );
         }
         else
         {
             child = children[pos].getValue();
-            deleteResult = child.delete( revision, key, value, this, pos );
+            deleteResult = ((AbstractPage<K, V>)child).delete( key, value, revision, this, pos );
         }
 
         // If the key is not present in the tree, we simply return
@@ -604,7 +604,7 @@
                 // We will remove one element from a page that will have less than N/2 elements,
                 // which will lead to some reorganization : either we can borrow an element from
                 // a sibling, or we will have to merge two pages
-                int siblingPos = selectSibling( ( InMemoryNode<K, V> ) parent, parentPos );
+                int siblingPos = selectSibling( parent, parentPos );
 
                 InMemoryNode<K, V> sibling = ( InMemoryNode<K, V> ) ( ( ( InMemoryNode<K, V> ) parent ).children[siblingPos]
                     .getValue() );
@@ -717,7 +717,7 @@
 
     /**
      * Remove the key at a given position.
-     * 
+     *
      * @param mergedResult The page we will remove a key from
      * @param revision The revision of the modified page
      * @param pos The position into the page of the element to remove
@@ -780,7 +780,7 @@
 
     /**
      * Set the value at a give position
-     * 
+     *
      * @param pos The position in the values array
      * @param value the value to inject
      */
@@ -794,7 +794,7 @@
      * This method is used when we have to replace a child in a page when we have
      * found the key in the tree (the value will be changed, so we have made
      * copies of the existing pages).
-     * 
+     *
      * @param revision The current revision
      * @param result The modified page
      * @param pos The position of the found key
@@ -825,7 +825,7 @@
     /**
      * Adds a new key into a copy of the current page at a given position. We return the
      * modified page. The new page will have one more key than the current page.
-     * 
+     *
      * @param copiedPages the list of copied pages
      * @param revision The revision of the modified page
      * @param key The key to insert
@@ -880,7 +880,7 @@
      * If the newly added element is in the middle, we will use it
      * as a pivot. Otherwise, we will use either the last element in the left page if the element is added
      * on the left, or the first element in the right page if it's added on the right.
-     * 
+     *
      * @param copiedPages the list of copied pages
      * @param revision The new revision for all the created pages
      * @param pivot The key that will be move up after the split
@@ -978,7 +978,7 @@
 
     /**
      * Copies the current page and all its keys, with a new revision.
-     * 
+     *
      * @param revision The new revision
      * @return The copied page
      */
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryTransactionManager.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryTransactionManager.java
new file mode 100644
index 0000000..ef9afb5
--- /dev/null
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryTransactionManager.java
@@ -0,0 +1,143 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * An implementation of a TransactionManager for in-memory B-trees
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class InMemoryTransactionManager extends AbstractTransactionManager
+{
+    /** A lock to protect the transaction handling */
+    private Lock transactionLock = new ReentrantLock();
+    
+    /** A ThreadLocalStorage used to store the current transaction */
+    private static final ThreadLocal<Integer> context = new ThreadLocal<Integer>();
+    
+    /** A Map keeping the latest revisions for each managed BTree */
+    private Map<String, BTreeHeader<?, ?>> currentBTreeHeaders = new HashMap<String, BTreeHeader<?, ?>>();
+
+    /** A Map storing the new revisions when some change have been made in some BTrees */
+    private Map<String, BTreeHeader<?, ?>> newBTreeHeaders = new HashMap<String, BTreeHeader<?, ?>>();
+    
+    /** A lock to protect the BtreeHeader maps */
+    private ReadWriteLock btreeHeadersLock = new ReentrantReadWriteLock();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void beginTransaction()
+    {
+        // First, take the lock
+        transactionLock.lock();
+        
+        // Now, check the TLS state
+        Integer nbTxnLevel = context.get();
+        
+        if ( nbTxnLevel == null )
+        {
+            context.set( 1 );
+        }
+        else
+        {
+            // And increment the counter of inner txn.
+            context.set( nbTxnLevel + 1 );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void commit()
+    {
+        int nbTxnStarted = context.get();
+        
+        if ( nbTxnStarted == 0 )
+        {
+            // The transaction was rollbacked, quit immediatelly
+            transactionLock.unlock();
+            
+            return;
+        }
+        else
+        {
+            
+            // And decrement the number of started transactions
+            context.set( nbTxnStarted - 1 );
+        }
+
+        // Finally, release the global lock
+        transactionLock.unlock();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void rollback()
+    {
+        // Reset the counter
+        context.set( 0 );
+
+        // Finally, release the global lock
+        transactionLock.unlock();
+    }
+    
+    
+    /**
+     * Get the current BTreeHeader for a given Btree. It might not exist
+     */
+    public BTreeHeader getBTreeHeader( String name )
+    {
+        // Get a lock
+        btreeHeadersLock.readLock().lock();
+        
+        // get the current BTree Header for this BTree and revision
+        BTreeHeader<?, ?> btreeHeader = currentBTreeHeaders.get( name );
+        
+        // And unlock 
+        btreeHeadersLock.readLock().unlock();
+
+        return btreeHeader;
+    }
+
+
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void updateNewBTreeHeaders( BTreeHeader btreeHeader )
+    {
+        newBTreeHeaders.put( btreeHeader.getBtree().getName(), btreeHeader );
+    }
+}
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryValueHolder.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryValueHolder.java
index db1aa73..369c23b 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryValueHolder.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryValueHolder.java
@@ -27,6 +27,7 @@
 
 import org.apache.directory.mavibot.btree.exception.BTreeOperationException;
 import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 
 
 /**
@@ -201,6 +202,10 @@
             {
                 throw new BTreeOperationException( e );
             }
+            catch ( KeyNotFoundException knfe )
+            {
+                throw new BTreeOperationException( knfe );
+            }
         }
 
         return returnedValue;
@@ -249,6 +254,12 @@
                 e.printStackTrace();
                 return false;
             }
+            catch ( KeyNotFoundException knfe )
+            {
+                // TODO Auto-generated catch block
+                knfe.printStackTrace();
+                return false;
+            }
         }
         else
         {
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/MavibotInspector.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/MavibotInspector.java
new file mode 100644
index 0000000..2777243
--- /dev/null
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/MavibotInspector.java
@@ -0,0 +1,1345 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree;
+
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.RandomAccessFile;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.directory.mavibot.btree.exception.InvalidBTreeException;
+import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
+import org.apache.directory.mavibot.btree.serializer.LongSerializer;
+import org.apache.directory.mavibot.btree.serializer.StringSerializer;
+import org.apache.directory.mavibot.btree.util.Strings;
+
+
+/**
+ * A class to examine a Mavibot database file.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class MavibotInspector
+{
+    // The file to be read
+    private File dbFile;
+
+    // The recordManager
+    private RecordManager rm;
+
+    private BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
+
+    // The name of the two page arrays for the global file and teh free pages
+    private static final String GLOBAL_PAGES_NAME = "__global__";
+    private static final String FREE_PAGES_NAME = "__free-pages__";
+
+    // The set of page array we already know about
+    private static Set<String> knownPagesArrays =  new HashSet<String>();
+    
+    static
+    {
+        knownPagesArrays.add( GLOBAL_PAGES_NAME );
+        knownPagesArrays.add( FREE_PAGES_NAME );
+        knownPagesArrays.add( RecordManager.BTREE_OF_BTREES_NAME );
+        knownPagesArrays.add( RecordManager.COPIED_PAGE_BTREE_NAME );
+    }
+    
+    /**
+     * A private class to store a few informations about a btree
+     *
+    
+    private static BtreeInfo btreeInfo;
+    
+    static
+    {
+        btreeInfo = new BtreeInfo();
+    }
+
+    /**
+     * Create an instance of MavibotInspector
+     * @param dbFile The file to read
+     */
+    public MavibotInspector( File dbFile )
+    {
+        this.dbFile = dbFile;
+    }
+
+
+    /**
+     * Check that the file exists
+     */
+    private boolean checkFilePresence()
+    {
+        if ( dbFile == null )
+        {
+            System.out.println( "No mavibot database file was given" );
+            return false;
+        }
+
+        if ( !dbFile.exists() )
+        {
+            System.out.println( "Given mavibot database file " + dbFile + " doesn't exist" );
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Pretty print the file size
+     */
+    public void printFileSize() throws IOException
+    {
+        FileChannel fileChannel = new RandomAccessFile( dbFile, "r" ).getChannel();
+
+        long l = fileChannel.size();
+
+        fileChannel.close();
+
+        String msg;
+
+        if ( l < 1024 )
+        {
+            msg = l + " bytes";
+        }
+        else
+        {
+            msg = ( l / 1024 ) + " KB";
+        }
+
+        System.out.println( msg );
+        
+        fileChannel.close();
+    }
+
+
+    /**
+     * Print the number of B-trees
+     */
+    public void printNumberOfBTrees()
+    {
+        int nbBtrees = 0;
+        
+        if ( rm != null )
+        {
+            nbBtrees = rm.getNbManagedTrees();
+        }
+
+        // The number of trees. It must be at least 2 and > 0
+        System.out.println( "Total Number of BTrees: " + nbBtrees );
+    }
+
+
+    /**
+     * Print the B-tree's name
+     */
+    public void printBTreeNames()
+    {
+        if ( rm == null )
+        {
+            System.out.println( "Couldn't find the number of managed btrees" );
+            return;
+        }
+
+        Set<String> trees = rm.getManagedTrees();
+        System.out.println( "\nManaged BTrees:" );
+        
+        for ( String tree : trees )
+        {
+            System.out.println( tree );
+        }
+        
+        System.out.println();
+    }
+
+
+    /**
+     * Check a B-tree
+     */
+    public void checkBTree()
+    {
+        if ( rm == null )
+        {
+            System.out.println( "Cannot check BTree(s)" );
+            return;
+        }
+
+        System.out.print( "BTree Name: " );
+        String name = readLine();
+
+        PersistedBTree<?, ?> pb = ( PersistedBTree<?, ?> ) rm.getManagedTree( name );
+
+        if ( pb == null )
+        {
+            System.out.println( "No BTree exists with the name '" + name + "'" );
+            return;
+        }
+
+        System.out.println( "\nBTree offset: " + String.format( "0x%1$08x", pb.getBtreeOffset() ) );
+        System.out.println( "BTree _info_ offset: " + String.format( "0x%1$08x", pb.getBtreeInfoOffset() ) );
+        System.out.println( "BTree root page offset: " + String.format( "0x%1$08x", pb.getRootPageOffset() ) );
+        System.out.println( "Number of elements present: " + pb.getNbElems() );
+        System.out.println( "BTree Page size: " + pb.getPageSize() );
+        System.out.println( "BTree revision: " + pb.getRevision() );
+        System.out.println( "Key serializer: " + pb.getKeySerializerFQCN() );
+        System.out.println( "Value serializer: " + pb.getValueSerializerFQCN() );
+        System.out.println();
+    }
+
+
+    /**
+     * Load the full fie into a new RecordManager
+     */
+    private boolean loadRm()
+    {
+        try
+        {
+            if( rm != null )
+            {
+                System.out.println("Closing record manager");
+                rm.close();
+            }
+            
+            rm = new RecordManager( dbFile.getAbsolutePath() );
+            System.out.println("Loaded record manager");
+        }
+        catch ( Exception e )
+        {
+            System.out.println( "Given database file seems to be corrupted. " + e.getMessage() );
+            return false;
+        }
+
+        return true;
+    }
+    
+    
+    /**
+     * Check the whole file
+     */
+    /* no qualifier */ static void check( RecordManager recordManager )
+    {
+        try
+        {
+            // First check the RMheader
+            ByteBuffer recordManagerHeader = ByteBuffer.allocate( RecordManager.RECORD_MANAGER_HEADER_SIZE );
+            long fileSize = recordManager.fileChannel.size();
+
+            if ( fileSize < RecordManager.RECORD_MANAGER_HEADER_SIZE )
+            {
+                throw new InvalidBTreeException( "File size too small : " + fileSize );
+            }
+
+            // Read the RMHeader
+            recordManager.fileChannel.read( recordManagerHeader, 0L );
+            recordManagerHeader.flip();
+
+            // The page size. It must be a power of 2, and above 16.
+            int pageSize = recordManagerHeader.getInt();
+
+            if ( ( pageSize != recordManager.pageSize ) || ( pageSize < 32 ) || ( ( pageSize & ( ~pageSize + 1 ) ) != pageSize ) )
+            {
+                throw new InvalidBTreeException( "Wrong page size : " + pageSize );
+            }
+
+            // Compute the number of pages in this file
+            long nbPages = ( fileSize - RecordManager.RECORD_MANAGER_HEADER_SIZE ) / pageSize;
+
+            // The number of trees. It must be at least 2 and > 0
+            int nbBtrees = recordManagerHeader.getInt();
+
+            if ( ( nbBtrees < 0 ) || ( nbBtrees != recordManager.nbBtree ) )
+            {
+                throw new InvalidBTreeException( "Wrong nb trees : " + nbBtrees );
+            }
+
+            // The first free page offset. It must be either -1 or below file size
+            // and its value must be a modulo of pageSize
+            long firstFreePage = recordManagerHeader.getLong();
+
+            checkOffset( recordManager, firstFreePage );
+
+            int nbPageBits = ( int ) ( nbPages / 32 );
+
+            // Create an array of pages to be checked for each B-tree, plus
+            // two others for the free pages and the global one
+            // We use one bit per page. It's 0 when the page
+            // hasn't been checked, 1 otherwise.
+            Map<String, int[]> checkedPages = new HashMap<String, int[]>(nbBtrees + 4);
+
+            // The global page array
+            checkedPages.put( GLOBAL_PAGES_NAME, new int[nbPageBits + 1] );
+
+            // The freePages array
+            checkedPages.put( FREE_PAGES_NAME, new int[nbPageBits + 1] );
+            
+            // The B-tree of B-trees array
+            checkedPages.put( RecordManager.BTREE_OF_BTREES_NAME, new int[nbPageBits + 1] );
+            
+            // Last, the Copied Pages B-tree array
+            checkedPages.put( RecordManager.COPIED_PAGE_BTREE_NAME, new int[nbPageBits + 1] );
+
+            // Check the free files
+            checkFreePages( recordManager, checkedPages );
+
+            // The B-trees offsets
+            long currentBtreeOfBtreesOffset = recordManagerHeader.getLong();
+            long previousBtreeOfBtreesOffset = recordManagerHeader.getLong();
+            long currentCopiedPagesBtreeOffset = recordManagerHeader.getLong();
+            long previousCopiedPagesBtreeOffset = recordManagerHeader.getLong();
+
+            // Check that the previous BOB offset is not pointing to something
+            if ( previousBtreeOfBtreesOffset != RecordManager.NO_PAGE )
+            {
+                System.out.println( "The previous Btree of Btrees offset is not valid : "
+                    + previousBtreeOfBtreesOffset );
+                return;
+            }
+
+            // Check that the previous CPB offset is not pointing to something
+            if ( previousCopiedPagesBtreeOffset != RecordManager.NO_PAGE )
+            {
+                System.out.println( "The previous Copied Pages Btree offset is not valid : "
+                    + previousCopiedPagesBtreeOffset );
+                return;
+            }
+
+            // Check that the current BOB offset is valid
+            checkOffset( recordManager, currentBtreeOfBtreesOffset );
+
+            // Check that the current CPB offset is valid
+            checkOffset( recordManager, currentCopiedPagesBtreeOffset );
+
+            // Now, check the BTree of Btrees
+            checkBtreeOfBtrees( recordManager, checkedPages );
+
+            // And the Copied Pages BTree
+            checkBtree( recordManager, currentCopiedPagesBtreeOffset, checkedPages );
+
+            // We can now dump the checked pages
+            dumpCheckedPages( recordManager, checkedPages );
+        }
+        catch ( Exception e )
+        {
+            // We catch the exception and rethrow it immediately to be able to
+            // put a breakpoint here
+            e.printStackTrace();
+            throw new InvalidBTreeException( "Error : " + e.getMessage() );
+        }
+    }
+
+    
+    /**
+     * Check the Btree of Btrees
+     */
+    private static <K, V> void checkBtreeOfBtrees( RecordManager recordManager, Map<String, int[]> checkedPages ) throws Exception
+    {
+        // Read the BOB header
+        PageIO[] bobHeaderPageIos = recordManager.readPageIOs( recordManager.currentBtreeOfBtreesOffset, Long.MAX_VALUE );
+
+        // update the checkedPages
+        updateCheckedPages( checkedPages.get( RecordManager.BTREE_OF_BTREES_NAME), recordManager.pageSize, bobHeaderPageIos );
+        updateCheckedPages( checkedPages.get( GLOBAL_PAGES_NAME ), recordManager.pageSize, bobHeaderPageIos );
+
+        long dataPos = 0L;
+
+        // The B-tree current revision
+        recordManager.readLong( bobHeaderPageIos, dataPos );
+        dataPos += RecordManager.LONG_SIZE;
+
+        // The nb elems in the tree
+        recordManager.readLong( bobHeaderPageIos, dataPos );
+        dataPos += RecordManager.LONG_SIZE;
+
+        // The B-tree rootPage offset
+        long rootPageOffset = recordManager.readLong( bobHeaderPageIos, dataPos );
+
+        checkOffset( recordManager, rootPageOffset );
+
+        dataPos += RecordManager.LONG_SIZE;
+
+        // The B-tree info offset
+        long btreeInfoOffset = recordManager.readLong( bobHeaderPageIos, dataPos );
+
+        checkOffset( recordManager, btreeInfoOffset );
+
+        checkBtreeInfo( recordManager, checkedPages, btreeInfoOffset, -1L );
+
+        // Check the elements in the btree itself
+        // We will read every single page
+        checkBtreeOfBtreesPage( recordManager, checkedPages, rootPageOffset );
+    }
+
+    
+    /**
+     * Check a user's B-tree
+     */
+    private static <K, V> void checkBtree( RecordManager recordManager, long btreeOffset, Map<String, int[]> checkedPages ) throws Exception
+    {
+        // Read the B-tree header
+        PageIO[] btreeHeaderPageIos = recordManager.readPageIOs( btreeOffset, Long.MAX_VALUE );
+
+        long dataPos = 0L;
+
+        // The B-tree current revision
+        long btreeRevision = recordManager.readLong( btreeHeaderPageIos, dataPos );
+        dataPos += RecordManager.LONG_SIZE;
+
+        // The nb elems in the tree
+        recordManager.readLong( btreeHeaderPageIos, dataPos );
+        dataPos += RecordManager.LONG_SIZE;
+
+        // The B-tree rootPage offset
+        long rootPageOffset = recordManager.readLong( btreeHeaderPageIos, dataPos );
+
+        checkOffset( recordManager, rootPageOffset );
+
+        dataPos += RecordManager.LONG_SIZE;
+
+        // The B-tree info offset
+        long btreeInfoOffset = recordManager.readLong( btreeHeaderPageIos, dataPos );
+
+        checkOffset( recordManager, btreeInfoOffset );
+
+        BtreeInfo<K, V> btreeInfo = checkBtreeInfo( recordManager, checkedPages, btreeInfoOffset, btreeRevision );
+
+        // Update the checked pages
+        updateCheckedPages( checkedPages.get( btreeInfo.btreeName ), recordManager.pageSize, btreeHeaderPageIos );
+        updateCheckedPages( checkedPages.get( GLOBAL_PAGES_NAME ), recordManager.pageSize, btreeHeaderPageIos );
+        
+        // And now, process the rootPage
+        checkBtreePage( recordManager, btreeInfo, checkedPages, rootPageOffset );
+    }
+
+    
+    /**
+     * Check the Btree of Btrees rootPage
+     */
+    private static <K, V> void checkBtreePage( RecordManager recordManager, BtreeInfo<K, V> btreeInfo, Map<String, int[]> checkedPages, long pageOffset ) throws Exception
+    {
+        PageIO[] pageIos = recordManager.readPageIOs( pageOffset, Long.MAX_VALUE );
+
+        // Update the checkedPages array
+        updateCheckedPages( checkedPages.get( btreeInfo.btreeName ), recordManager.pageSize, pageIos );
+        updateCheckedPages( checkedPages.get( GLOBAL_PAGES_NAME ), recordManager.pageSize, pageIos );
+
+        // Deserialize the page now
+        long position = 0L;
+
+        // The revision
+        long revision = recordManager.readLong( pageIos, position );
+        position += RecordManager.LONG_SIZE;
+
+        // The number of elements in the page
+        int nbElems = recordManager.readInt( pageIos, position );
+        position += RecordManager.INT_SIZE;
+
+        // The size of the data containing the keys and values
+        // Reads the bytes containing all the keys and values, if we have some
+        // We read  big blob of data into  ByteBuffer, then we will process
+        // this ByteBuffer
+        ByteBuffer byteBuffer = recordManager.readBytes( pageIos, position );
+
+        // Now, deserialize the data block. If the number of elements
+        // is positive, it's a Leaf, otherwise it's a Node
+        // Note that only a leaf can have 0 elements, and it's the root page then.
+        if ( nbElems >= 0 )
+        {
+            // It's a leaf, process it as we may have sub-btrees
+            checkBtreeLeaf( recordManager, btreeInfo, checkedPages, nbElems, revision, byteBuffer, pageIos );
+        }
+        else
+        {
+            // It's a node
+            long[] children = checkBtreeNode( recordManager, btreeInfo, checkedPages, -nbElems, revision, byteBuffer, pageIos );
+
+            for ( int pos = 0; pos <= -nbElems; pos++ )
+            {
+                // Recursively check the children
+                checkBtreePage( recordManager, btreeInfo, checkedPages, children[pos] );
+            }
+        }
+    }
+
+    
+    /**
+     * Check the Btree info page
+     * @throws ClassNotFoundException 
+     */
+    private static <K, V> BtreeInfo<K, V> checkBtreeInfo( RecordManager recordManager, Map<String, int[]> checkedPages, long btreeInfoOffset, long btreeRevision ) throws IOException
+    {
+        BtreeInfo<K, V> btreeInfo = new BtreeInfo<K, V>();
+        
+        PageIO[] btreeInfoPagesIos = recordManager.readPageIOs( btreeInfoOffset, Long.MAX_VALUE );
+
+        long dataPos = 0L;
+
+        // The B-tree page size
+        recordManager.readInt( btreeInfoPagesIos, dataPos );
+        dataPos += RecordManager.INT_SIZE;
+
+        // The tree name
+        ByteBuffer btreeNameBytes = recordManager.readBytes( btreeInfoPagesIos, dataPos );
+        dataPos += RecordManager.INT_SIZE + btreeNameBytes.limit();
+        String btreeName = Strings.utf8ToString( btreeNameBytes );
+
+        // The keySerializer FQCN
+        ByteBuffer keySerializerBytes = recordManager.readBytes( btreeInfoPagesIos, dataPos );
+
+        if ( keySerializerBytes != null )
+        {
+            String keySerializerFqcn = Strings.utf8ToString( keySerializerBytes );
+            
+            btreeInfo.keySerializer = getSerializer(  keySerializerFqcn );
+        }
+
+        dataPos += RecordManager.INT_SIZE + keySerializerBytes.limit();
+
+        // The valueSerialier FQCN
+        ByteBuffer valueSerializerBytes = recordManager.readBytes( btreeInfoPagesIos, dataPos );
+
+        if ( valueSerializerBytes != null )
+        {
+            String valueSerializerFqcn = Strings.utf8ToString( valueSerializerBytes );
+            
+            btreeInfo.valueSerializer = getSerializer( valueSerializerFqcn );
+        }
+
+        dataPos += RecordManager.INT_SIZE + valueSerializerBytes.limit();
+
+        // The B-tree allowDuplicates flag
+        recordManager.readInt( btreeInfoPagesIos, dataPos );
+        dataPos += RecordManager.INT_SIZE;
+
+        // update the checkedPages
+        if ( !RecordManager.COPIED_PAGE_BTREE_NAME.equals( btreeName ) && !RecordManager.BTREE_OF_BTREES_NAME.equals( btreeName ) )
+        {
+            btreeName = btreeName + "<" + btreeRevision + ">";
+        }
+
+        btreeInfo.btreeName = btreeName;
+        
+        // Update the checkedPages
+        int[] checkedPagesArray = checkedPages.get( btreeName );
+        
+        if ( checkedPagesArray == null )
+        {
+            // Add the new name in the checkedPage name if it's not already there
+            checkedPagesArray = createPageArray( recordManager );
+            checkedPages.put( btreeName, checkedPagesArray );
+        }
+        
+        updateCheckedPages( checkedPagesArray, recordManager.pageSize, btreeInfoPagesIos );
+        updateCheckedPages( checkedPages.get( GLOBAL_PAGES_NAME ), recordManager.pageSize, btreeInfoPagesIos );
+        
+        return btreeInfo;
+    }
+    
+
+    /**
+     * Get back the serializer instance
+     */
+    @SuppressWarnings("unchecked")
+    private static <T> ElementSerializer<T> getSerializer( String serializerFqcn )
+    {
+        try
+        {
+            Class<?> serializerClass = Class.forName( serializerFqcn );
+            ElementSerializer<T> serializer = null;
+            
+            try
+            {
+                serializer = ( ElementSerializer<T> ) serializerClass.getDeclaredField( "INSTANCE" ).get( null );
+            }
+            catch( NoSuchFieldException e )
+            {
+                // ignore
+            }
+    
+            if ( serializer == null )
+            {
+                serializer = ( ElementSerializer<T> ) serializerClass.newInstance();
+            }
+    
+            return serializer;
+        }
+        catch ( Exception e )
+        {
+            throw new InvalidBTreeException( "Error : " + e.getMessage() );
+        }
+    }
+
+    
+    /**
+     * Check the Btree of Btrees rootPage
+     */
+    private static <K, V> void checkBtreeOfBtreesPage( RecordManager recordManager, Map<String, int[]> checkedPages, long pageOffset ) throws Exception
+    {
+        PageIO[] pageIos = recordManager.readPageIOs( pageOffset, Long.MAX_VALUE );
+
+        // Update the checkedPages array
+        updateCheckedPages( checkedPages.get( RecordManager.BTREE_OF_BTREES_NAME), recordManager.pageSize, pageIos );
+        updateCheckedPages( checkedPages.get( GLOBAL_PAGES_NAME ), recordManager.pageSize, pageIos );
+
+        // Deserialize the page now
+        long position = 0L;
+
+        // The revision
+        long revision = recordManager.readLong( pageIos, position );
+        position += RecordManager.LONG_SIZE;
+
+        // The number of elements in the page
+        int nbElems = recordManager.readInt( pageIos, position );
+        position += RecordManager.INT_SIZE;
+
+        // The size of the data containing the keys and values
+        // Reads the bytes containing all the keys and values, if we have some
+        // We read  big blob of data into  ByteBuffer, then we will process
+        // this ByteBuffer
+        ByteBuffer byteBuffer = recordManager.readBytes( pageIos, position );
+
+        // Now, deserialize the data block. If the number of elements
+        // is positive, it's a Leaf, otherwise it's a Node
+        // Note that only a leaf can have 0 elements, and it's the root page then.
+        if ( nbElems >= 0 )
+        {
+            // It's a leaf, process it as we may have sub-btrees
+            checkBtreeOfBtreesLeaf( recordManager, checkedPages, nbElems, revision, byteBuffer, pageIos );
+        }
+        else
+        {
+            // It's a node
+            long[] children = checkBtreeOfBtreesNode( recordManager, checkedPages, -nbElems, revision, byteBuffer, pageIos );
+
+            for ( int pos = 0; pos <= -nbElems; pos++ )
+            {
+                // Recursively check the children
+                checkBtreeOfBtreesPage( recordManager, checkedPages, children[pos] );
+            }
+        }
+    }
+    
+    
+    /**
+     * Check a Btree of Btrees leaf. It contains <revision, name> -> offset.
+     */
+    private static <K, V> void checkBtreeOfBtreesLeaf( RecordManager recordManager, Map<String, int[]> checkedPages, int nbElems, long revision, ByteBuffer byteBuffer, PageIO[] pageIos ) throws Exception
+    {
+        // Read each key and value
+        for ( int i = 0; i < nbElems; i++ )
+        {
+            try
+            {
+                // Read the number of values
+                int nbValues = byteBuffer.getInt();
+    
+                if ( nbValues != 1 )
+                {
+                    throw new InvalidBTreeException( "We should have only one value for a BOB " + nbValues );
+                }
+    
+                // This is a normal value
+                // First, the value, which is an offset, which length should be 12
+                int valueLength = byteBuffer.getInt();
+                
+                if ( valueLength != RecordManager.LONG_SIZE + RecordManager.INT_SIZE )
+                {
+                    throw new InvalidBTreeException( "The BOB value length is invalid " + valueLength );
+                }
+    
+                // Second, the offset length, which should be 8
+                int offsetLength = byteBuffer.getInt();
+                
+                if ( offsetLength != RecordManager.LONG_SIZE )
+                {
+                    throw new InvalidBTreeException( "The BOB value offset length is invalid " + offsetLength );
+                }
+                
+                // Then the offset
+                long btreeOffset = byteBuffer.getLong();
+                
+                checkOffset( recordManager, btreeOffset );
+                
+                // Now, process the key
+                // First the key length
+                int keyLength = byteBuffer.getInt();
+    
+                // The length should be at least 12 bytes long
+                if ( keyLength < RecordManager.LONG_SIZE + RecordManager.INT_SIZE )
+                {
+                    throw new InvalidBTreeException( "The BOB key length is invalid " + keyLength );
+                }
+                
+                // Read the revision
+                long btreeRevision = byteBuffer.getLong();
+                
+                // read the btreeName
+                int btreeNameLength = byteBuffer.getInt();
+    
+                // The length should be equals to the btreeRevision + btreeNameLength + 4
+                if ( keyLength != RecordManager.LONG_SIZE + RecordManager.INT_SIZE + btreeNameLength )
+                {
+                    throw new InvalidBTreeException( "The BOB key length is not the expected value " + 
+                        ( RecordManager.LONG_SIZE + RecordManager.INT_SIZE + btreeNameLength ) + ", expected " + keyLength );
+                }
+                
+                byte[] bytes = new byte[btreeNameLength];
+                byteBuffer.get( bytes );
+                String btreeName = Strings.utf8ToString( bytes );
+                
+                // Add the new name in the checkedPage name if it's not already there
+                int[] btreePagesArray = createPageArray( recordManager );
+                checkedPages.put( btreeName + "<" + btreeRevision + ">", btreePagesArray );
+                
+                // Now, we can check the Btree we just found
+                checkBtree( recordManager, btreeOffset, checkedPages );
+                
+                //System.out.println( "read <" + btreeName + "," + btreeRevision + "> : 0x" + Long.toHexString( btreeOffset ) );
+            }
+            catch ( BufferUnderflowException bue )
+            {
+                throw new InvalidBTreeException( "The BOB leaf byte buffer is too short : " + bue.getMessage() );
+            }
+        }
+    }
+    
+    
+    /**
+     * Check a Btree leaf.
+     */
+    private static <K, V> void checkBtreeLeaf( RecordManager recordManager, BtreeInfo<K, V> btreeInfo, Map<String, int[]> checkedPages, int nbElems, long revision, ByteBuffer byteBuffer, PageIO[] pageIos ) throws Exception
+    {
+        // Read each key and value
+        for ( int i = 0; i < nbElems; i++ )
+        {
+            try
+            {
+                // Read the number of values
+                int nbValues = byteBuffer.getInt();
+    
+                if ( nbValues < 0 )
+                {
+                    // This is a sub-btree. Read the offset
+                    long subBtreeOffset = byteBuffer.getLong();
+                    
+                    // And process the sub-btree
+                    checkBtree( recordManager, subBtreeOffset, checkedPages );
+                    
+                    // Now, process the key
+                    // The key length
+                    byteBuffer.getInt();
+                    
+                    // The key itself
+                    btreeInfo.keySerializer.deserialize( byteBuffer );
+                }
+                else
+                {
+                    // just deserialize the keys and values
+                    // The value
+                    byteBuffer.getInt();
+                    btreeInfo.valueSerializer.deserialize( byteBuffer );
+                    
+                    // the key
+                    byteBuffer.getInt();
+                    
+                    btreeInfo.keySerializer.deserialize( byteBuffer );
+                }
+            }
+            catch ( BufferUnderflowException bue )
+            {
+                throw new InvalidBTreeException( "The BOB leaf byte buffer is too short : " + bue.getMessage() );
+            }
+        }
+    }
+    
+    /**
+     * Check a Btree of Btrees Node
+     */
+    private static <K, V> long[] checkBtreeOfBtreesNode( RecordManager recordManager, Map<String, int[]> checkedPages, int nbElems, long revision,
+        ByteBuffer byteBuffer, PageIO[] pageIos ) throws IOException
+    {
+        long[] children = new long[nbElems + 1];
+
+        // Read each value
+        for ( int i = 0; i < nbElems; i++ )
+        {
+            // The offsets of the child
+            long firstOffset = LongSerializer.INSTANCE.deserialize( byteBuffer );
+            
+            checkOffset( recordManager, firstOffset );
+            
+            long lastOffset = LongSerializer.INSTANCE.deserialize( byteBuffer );
+
+            checkOffset( recordManager, lastOffset );
+            
+            children[i] = firstOffset;
+
+            // Read the key length
+            int keyLength = byteBuffer.getInt();
+            
+            // The length should be at least 12 bytes long
+            if ( keyLength < RecordManager.LONG_SIZE + RecordManager.INT_SIZE )
+            {
+                throw new InvalidBTreeException( "The BOB key length is invalid " + keyLength );
+            }
+            
+            // Read the revision
+            byteBuffer.getLong();
+            
+            // read the btreeName
+            int btreeNameLength = byteBuffer.getInt();
+
+            // The length should be equals to the btreeRevision + btreeNameLength + 4
+            if ( keyLength != RecordManager.LONG_SIZE + RecordManager.INT_SIZE + btreeNameLength )
+            {
+                throw new InvalidBTreeException( "The BOB key length is not the expected value " + 
+                    ( RecordManager.LONG_SIZE + RecordManager.INT_SIZE + btreeNameLength ) + ", expected " + keyLength );
+            }
+            
+            // Read the Btree name
+            byte[] bytes = new byte[btreeNameLength];
+            byteBuffer.get( bytes );
+        }
+
+        // And read the last child
+        // The offsets of the child
+        long firstOffset = LongSerializer.INSTANCE.deserialize( byteBuffer );
+        
+        checkOffset( recordManager, firstOffset );
+        
+        long lastOffset = LongSerializer.INSTANCE.deserialize( byteBuffer );
+
+        checkOffset( recordManager, lastOffset );
+        
+        children[nbElems] = firstOffset;
+
+        // and read the last value, as it's a node
+        return children;
+    }
+    
+    
+    /**
+     * Check a Btree node.
+     */
+    private static <K, V> long[] checkBtreeNode( RecordManager recordManager, BtreeInfo<K, V> btreeInfo, Map<String, int[]> checkedPages, int nbElems, long revision, ByteBuffer byteBuffer, PageIO[] pageIos ) throws Exception
+    {
+        long[] children = new long[nbElems + 1];
+
+        // Read each key and value
+        for ( int i = 0; i < nbElems; i++ )
+        {
+            try
+            {
+                // The offsets of the child
+                long firstOffset = LongSerializer.INSTANCE.deserialize( byteBuffer );
+                
+                checkOffset( recordManager, firstOffset );
+                
+                long lastOffset = LongSerializer.INSTANCE.deserialize( byteBuffer );
+
+                checkOffset( recordManager, lastOffset );
+                
+                children[i] = firstOffset;
+                
+                // Now, read the key
+                // The key lenth
+                byteBuffer.getInt();
+                
+                // The key itself
+                btreeInfo.keySerializer.deserialize( byteBuffer );
+            }
+            catch ( BufferUnderflowException bue )
+            {
+                throw new InvalidBTreeException( "The BOB leaf byte buffer is too short : " + bue.getMessage() );
+            }
+        }
+        
+        // The last child
+        // The offsets of the child
+        long firstOffset = LongSerializer.INSTANCE.deserialize( byteBuffer );
+        
+        checkOffset( recordManager, firstOffset );
+        
+        long lastOffset = LongSerializer.INSTANCE.deserialize( byteBuffer );
+
+        checkOffset( recordManager, lastOffset );
+        
+        children[nbElems] = firstOffset;
+        
+        return children;
+    }
+    
+    
+    /**
+     * Create an array of bits for pages 
+     */
+    private static int[] createPageArray( RecordManager recordManager ) throws IOException
+    {
+        long fileSize = recordManager.fileChannel.size();
+        int pageSize = recordManager.pageSize;
+        long nbPages = ( fileSize - RecordManager.RECORD_MANAGER_HEADER_SIZE ) / pageSize;
+        int nbPageBits = ( int ) ( nbPages / 32 );
+        
+        return new int[nbPageBits + 1];
+    }
+
+
+    /**
+     * Update the array of seen pages.
+     */
+    private static void updateCheckedPages( int[] checkedPages, int pageSize, PageIO... pageIos )
+    {
+        for ( PageIO pageIO : pageIos )
+        {
+            long offset = pageIO.getOffset();
+
+            if ( ( offset % pageSize ) != 0 )
+            {
+                throw new InvalidBTreeException( "Offset invalid : " + offset );
+            }
+
+            int pageNumber = (int)(offset / pageSize);
+            int nbBitsPage = ( RecordManager.INT_SIZE << 3 );
+            int pageMask = checkedPages[ pageNumber / nbBitsPage ];
+            int mask = 1 << pageNumber % nbBitsPage;
+
+            if ( ( pageMask & mask ) != 0 )
+            {
+                //throw new InvalidBTreeException( "The page " + offset + " has already been referenced" );
+            }
+
+            pageMask |= mask;
+            checkedPages[ pageNumber / nbBitsPage ] = pageMask;
+        }
+    }
+
+
+    /**
+     * Check the offset to be sure it's a valid one :
+     * <ul>
+     * <li>It's >= 0</li>
+     * <li>It's below the end of the file</li>
+     * <li>It's a multiple of the pageSize
+     * </ul>
+     */
+    private static void checkOffset( RecordManager recordManager, long offset ) throws IOException
+    {
+        if ( ( offset == RecordManager.NO_PAGE ) ||
+             ( ( ( offset - RecordManager.RECORD_MANAGER_HEADER_SIZE ) % recordManager.pageSize ) != 0 ) ||
+             ( offset > recordManager.fileChannel.size() ) )
+        {
+            throw new InvalidBTreeException( "Invalid Offset : " + offset );
+        }
+    }
+
+
+    /**
+     * Check the free pages
+     */
+    private static void checkFreePages( RecordManager recordManager, Map<String, int[]> checkedPages )
+        throws IOException
+    {
+        if ( recordManager.firstFreePage == RecordManager.NO_PAGE )
+        {
+            return;
+        }
+
+        // Now, read all the free pages
+        long currentOffset = recordManager.firstFreePage;
+        long fileSize = recordManager.fileChannel.size();
+
+        while ( currentOffset != RecordManager.NO_PAGE )
+        {
+            if ( currentOffset > fileSize )
+            {
+                System.out.println( "Wrong free page offset, above file size : " + currentOffset );
+                return;
+            }
+
+            try
+            {
+                PageIO pageIo = recordManager.fetchPage( currentOffset );
+
+                if ( currentOffset != pageIo.getOffset() )
+                {
+                    System.out.println( "PageIO offset is incorrect : " + currentOffset + "-"
+                        + pageIo.getOffset() );
+                    return;
+                }
+
+                setCheckedPage( recordManager, checkedPages.get( GLOBAL_PAGES_NAME ), currentOffset );
+                setCheckedPage( recordManager, checkedPages.get( FREE_PAGES_NAME ), currentOffset );
+
+                long newOffset = pageIo.getNextPage();
+                currentOffset = newOffset;
+            }
+            catch ( IOException ioe )
+            {
+                throw new InvalidBTreeException( "Cannot fetch page at : " + currentOffset );
+            }
+        }
+    }
+
+    
+    /**
+     * Update the ChekcedPages array
+     */
+    private static void setCheckedPage( RecordManager recordManager, int[] checkedPages, long offset )
+    {
+        int pageNumber = ( int ) offset / recordManager.pageSize;
+        int nbBitsPage = ( RecordManager.INT_SIZE << 3 );
+        long pageMask = checkedPages[ pageNumber / nbBitsPage ];
+        long mask = 1L << pageNumber % nbBitsPage;
+        
+        if ( ( pageMask & mask ) != 0 )
+        {
+            //throw new InvalidBTreeException( "The page " + offset + " has already been referenced" );
+        }
+
+        pageMask |= mask;
+        
+        checkedPages[ pageNumber / nbBitsPage ] |= pageMask;
+    }
+
+
+    /**
+     * Output the pages that has been seen ('1') and those which has not been seen ('0'). The '.' represent non-pages
+     * at the end of the file.
+     */
+    private static void dumpCheckedPages( RecordManager recordManager, Map<String, int[]> checkedPages ) throws IOException
+    {
+        // First dump the global array
+        int[] globalArray = checkedPages.get( GLOBAL_PAGES_NAME );
+        String result = dumpPageArray( recordManager, globalArray );
+        
+        String dump = String.format( "%1$-40s : %2$s", GLOBAL_PAGES_NAME, result );
+        System.out.println( dump );
+        
+        // The free pages array
+        int[] freePagesArray = checkedPages.get( FREE_PAGES_NAME );
+        result = dumpPageArray( recordManager, freePagesArray );
+        
+        dump = String.format( "%1$-40s : %2$s", FREE_PAGES_NAME, result );
+        System.out.println( dump );
+        
+        // The B-tree of B-trees pages array
+        int[] btreeOfBtreesArray = checkedPages.get( RecordManager.BTREE_OF_BTREES_NAME );
+        result = dumpPageArray( recordManager, btreeOfBtreesArray );
+        
+        dump = String.format( "%1$-40s : %2$s", RecordManager.BTREE_OF_BTREES_NAME, result );
+        System.out.println( dump );
+        
+        // The Copied page B-tree pages array
+        int[] copiedPagesArray = checkedPages.get( RecordManager.COPIED_PAGE_BTREE_NAME );
+        result = dumpPageArray( recordManager, copiedPagesArray );
+        
+        dump = String.format( "%1$-40s : %2$s", RecordManager.COPIED_PAGE_BTREE_NAME, result );
+        System.out.println( dump );
+        
+        // And now, all the other btree arrays
+        for ( String btreeName : checkedPages.keySet() )
+        {
+            // Don't do the array we have already processed
+            if ( knownPagesArrays.contains( btreeName ) )
+            {
+                continue;
+            }
+
+            int[] btreePagesArray = checkedPages.get( btreeName );
+            result = dumpPageArray( recordManager, btreePagesArray );
+            
+            dump = String.format( "%1$-40s : %2$s", btreeName, result );
+            System.out.println( dump );
+        }
+    }
+
+    
+    /**
+     * Process a page array
+     */
+    private static String dumpPageArray( RecordManager recordManager, int[] checkedPages ) throws IOException
+    {
+        StringBuilder sb = new StringBuilder();
+        int i = -1;
+        int nbPagesChecked = 0;
+        long fileSize = recordManager.fileChannel.size();
+        long nbPages = ( fileSize - RecordManager.RECORD_MANAGER_HEADER_SIZE ) / recordManager.pageSize;
+
+        for ( int checkedPage : checkedPages )
+        {
+            if ( i == 0 )
+            {
+                sb.append( " " );
+                i++;
+            }
+            else
+            {
+                i = 0;
+            }
+
+            sb.append( "[" ).append( i ).append(  "] " );
+
+
+            for ( int j = 0; j < 32; j++ )
+            {
+                if ( nbPagesChecked >= nbPages + 1 )
+                {
+                    sb.append( "." );
+                }
+                else
+                {
+                    if ( ( checkedPage & ( 1 << j ) )  == 0 )
+                    {
+                        sb.append( "0" );
+                    }
+                    else
+                    {
+                        sb.append( "1" );
+                    }
+                }
+
+                nbPagesChecked++;
+            }
+        }
+
+        return sb.toString();
+    }
+    
+
+    /**
+     * The entry point method
+     */
+    public void start() throws Exception
+    {
+        if ( !checkFilePresence() )
+        {
+            return;
+        }
+
+        if ( !loadRm() )
+        {
+            return;
+        }
+
+        boolean stop = false;
+
+        while ( !stop )
+        {
+            System.out.println( "Choose an option:" );
+            System.out.println( "1. Print Number of BTrees" );
+            System.out.println( "2. Print BTree Names" );
+            System.out.println( "3. Inspect BTree" );
+            System.out.println( "4. Check Free Pages" );
+            System.out.println( "5. Get database file size" );
+            System.out.println( "6. Dump RecordManager" );
+            System.out.println( "7. Reload RecordManager" );
+            System.out.println( "q. Quit" );
+
+            char c = readOption();
+
+            switch ( c )
+            {
+                case '1':
+                    printNumberOfBTrees();
+                    break;
+
+                case '2':
+                    printBTreeNames();
+                    break;
+
+                case '3':
+                    checkBTree();
+                    break;
+
+                case '4':
+                    long fileSize = rm.fileChannel.size();
+                    long nbPages = fileSize / rm.pageSize;
+                    int nbPageBits = ( int ) ( nbPages / RecordManager.INT_SIZE );
+
+                    Map<String, int[]> checkedPages = new HashMap<String, int[]>(2);
+
+                    // The global page array
+                    checkedPages.put( GLOBAL_PAGES_NAME, new int[nbPageBits + 1] );
+
+                    // The freePages array
+                    checkedPages.put( FREE_PAGES_NAME, new int[nbPageBits + 1] );
+
+                    checkFreePages( rm, checkedPages );
+                    break;
+
+                case '5':
+                    printFileSize();
+                    break;
+
+                case '6':
+                    check( rm );
+                    break;
+
+                case '7':
+                    loadRm();
+                    break;
+
+                case 'q':
+                    stop = true;
+                    break;
+
+                default:
+                    System.out.println( "Invalid option" );
+                    //c = readOption( br );
+                    break;
+            }
+        }
+
+        try
+        {
+            rm.close();
+            br.close();
+        }
+        catch ( Exception e )
+        {
+            //ignore
+        }
+    }
+
+
+    /**
+     * Read the user's interaction
+     */
+    private String readLine()
+    {
+        try
+        {
+            return br.readLine().trim();
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    /**
+     * Process the input and get back the selected choice
+     */
+    private char readOption()
+    {
+        try
+        {
+            String s = br.readLine();
+
+            if ( s.length() == 0 )
+            {
+                return ' ';
+            }
+
+            return s.charAt( 0 );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    /**
+     * Main method
+     */
+    public static void main( String[] args ) throws Exception
+    {
+        File f = new File( "/tmp/mavibotispector.db" );
+
+        RecordManager rm = new RecordManager( f.getAbsolutePath() );
+        String name1 = "corpus";
+        String name2 = "multiValues";
+        /*
+        if ( !rm.getManagedTrees().contains( name1 ) )
+        {
+            rm.addBTree( name1, StringSerializer.INSTANCE, StringSerializer.INSTANCE, true );
+        }
+        */
+        if ( !rm.getManagedTrees().contains( name2 ) )
+        {
+            rm.addBTree( name2, StringSerializer.INSTANCE, StringSerializer.INSTANCE, true );
+        }
+
+        /*
+        // Load some elements in the single value btree
+        BTree<String, String> btree1 = rm.getManagedTree( name1 );
+        
+        for ( int i = 0; i < 10; i++ )
+        {
+            btree1.insert( Integer.toString( i ), Integer.toString( i ) );
+        }
+        */
+
+        // Load some elements in the multi value btree
+        BTree<String, String> btree2 = rm.getManagedTree( name2 );
+        
+        for ( int i = 0; i < 1; i++ )
+        {
+            for ( int j = 0; j < 10; j++)
+            {
+                btree2.insert( Integer.toString( i ), Integer.toString( j ) );
+            }
+        }
+
+        rm.close();
+        
+        MavibotInspector mi = new MavibotInspector( f );
+        mi.start();
+    }
+}
+
+
+/**
+ * A class used to store some information about the Btree 
+ */
+final class BtreeInfo<K, V>
+{
+    // The btree name
+    /* no qualifier */ String btreeName;
+    
+    // The key serializer
+    /* no qualifier */ElementSerializer<K> keySerializer;
+    
+    // The value serializer
+    /* no qualifier */ElementSerializer<V> valueSerializer;
+    
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        
+        sb.append( "B-tree Info :" );
+        sb.append( "\n    name              : " ).append( btreeName );
+        sb.append( "\n    key serializer    : " ).append( keySerializer.getClass().getName() );
+        sb.append( "\n    value serializer  : " ).append( valueSerializer.getClass().getName() );
+        
+        return sb.toString();
+    }
+}
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionComparator.java
index 215dea0..00ea577 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionComparator.java
@@ -30,6 +30,17 @@
  */
 /* no qualifier*/class NameRevisionComparator implements Comparator<NameRevision>
 {
+    /** A static instance of a NameRevisionComparator */
+    public static final NameRevisionComparator INSTANCE = new NameRevisionComparator();
+
+    /**
+     * A private constructor of the NameRevisionComparator class
+     */
+    private NameRevisionComparator()
+    {
+    }
+
+
     /**
      * {@inheritDoc}
      */
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionSerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionSerializer.java
index aac218d..a6c7a9d 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionSerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionSerializer.java
@@ -41,12 +41,15 @@
  */
 /* no qualifier*/class NameRevisionSerializer extends AbstractElementSerializer<NameRevision>
 {
+    /** A static instance of a NameRevisionSerializer */
+    /*No qualifier*/ final static NameRevisionSerializer INSTANCE = new NameRevisionSerializer();
+
     /**
      * Create a new instance of a NameRevisionSerializer
      */
-    /* no qualifier*/NameRevisionSerializer()
+    private NameRevisionSerializer()
     {
-        super( new NameRevisionComparator() );
+        super( NameRevisionComparator.INSTANCE );
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/Page.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/Page.java
index 5724e20..8056e54 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/Page.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/Page.java
@@ -31,7 +31,7 @@
  * (containing keys and references to child pages).<br/>
  * A Page can be stored on disk. If so, we store the serialized value of this Page into
  * one or more {@link PageIO} (they will be linked)
- * 
+ *
  * @param <K> The type for the Key
  * @param <V> The type for the stored value
  *
@@ -56,22 +56,22 @@
      * the Page is full, we split it and propagate the new pivot up into the tree</li>
      * </ul>
      * <p>
-     * 
-     * @param revision The new revision for the modified pages
+     *
      * @param key Inserted key
      * @param value Inserted value
+     * @param revision The new revision for the modified pages
      * @return Either a modified Page or an Overflow element if the Page was full
      * @throws IOException If we have an error while trying to access the page
      */
-    InsertResult<K, V> insert( long revision, K key, V value ) throws IOException;
+    InsertResult<K, V> insert( K key, V value, long revision ) throws IOException;
 
 
     /**
-     * Deletes the value from an entry associated with the given key in this page. We first find 
+     * Deletes the value from an entry associated with the given key in this page. We first find
      * the place were to remove the <K,V> into the tree, by recursively browsing the pages.
-     * If the value is present, it will be deleted first, later if there are no other values associated with 
+     * If the value is present, it will be deleted first, later if there are no other values associated with
      * this key(which can happen when duplicates are enabled), we will remove the key from the tree.
-     * 
+     *
      * @param revision The new revision for the modified pages
      * @param key The key to delete
      * @param value The value to delete (can be null)
@@ -80,15 +80,15 @@
      * @return Either a modified Page if the key has been removed from the page, or a NotPresentResult.
      * @throws IOException If we have an error while trying to access the page
      */
-    DeleteResult<K, V> delete( long revision, K key, V value, Page<K, V> parent, int parentPos ) throws IOException;
+    DeleteResult<K, V> delete( K key, V value, long revision /*, Page<K, V> parent, int parentPos*/ ) throws IOException;
 
 
     /**
-     * Gets the value associated with the given key, if any. If we don't have 
+     * Gets the value associated with the given key, if any. If we don't have
      * one, this method will throw a KeyNotFoundException.<br/>
-     * Note that we may get back null if a null value has been associated 
+     * Note that we may get back null if a null value has been associated
      * with the key.
-     * 
+     *
      * @param key The key we are looking for
      * @return The associated value, which can be null
      * @throws KeyNotFoundException If no entry with the given key can be found
@@ -98,23 +98,23 @@
 
 
     /**
-     * Gets the values associated with the given key, if any. If we don't have 
+     * Gets the values associated with the given key, if any. If we don't have
      * the key, this method will throw a KeyNotFoundException.<br/>
-     * Note that we may get back null if a null value has been associated 
+     * Note that we may get back null if a null value has been associated
      * with the key.
-     * 
+     *
      * @param key The key we are looking for
      * @return The associated value, which can be null
      * @throws KeyNotFoundException If no entry with the given key can be found
      * @throws IOException If we have an error while trying to access the page
-     * @throws IllegalArgumentException If duplicates are not enabled 
+     * @throws IllegalArgumentException If duplicates are not enabled
      */
     ValueCursor<V> getValues( K key ) throws KeyNotFoundException, IOException, IllegalArgumentException;
 
 
     /**
      * Checks if the page contains the given key with the given value.
-     * 
+     *
      * @param key The key we are looking for
      * @param value The value associated with the given key
      * @return true if the key and value are associated with each other, false otherwise
@@ -125,7 +125,7 @@
     /**
      * Browses the tree, looking for the given key, and creates a Cursor on top
      * of the found result.
-     * 
+     *
      * @param key The key we are looking for.
      * @param transaction The started transaction for this operation
      * @param stack The stack of parents we go through to get to this page
@@ -138,7 +138,7 @@
 
     /**
      * Browses the whole tree, and creates a Cursor on top of it.
-     * 
+     *
      * @param transaction The started transaction for this operation
      * @param stack The stack of parents we go through to get to this page
      * @return A Cursor to browse the next elements
@@ -156,7 +156,7 @@
 
     /**
      * Returns the key at a given position
-     * 
+     *
      * @param pos The position of the key we want to retrieve
      * @return The key found at the given position
      */
@@ -166,7 +166,7 @@
     /**
      * Finds the leftmost key in this page. If the page is a node, it will go
      * down in the leftmost children to recursively find the leftmost key.
-     * 
+     *
      * @return The leftmost key in the tree
      */
     K getLeftMostKey();
@@ -175,7 +175,7 @@
     /**
      * Finds the rightmost key in this page. If the page is a node, it will go
      * down in the rightmost children to recursively find the rightmost key.
-     * 
+     *
      * @return The rightmost key in the tree
      */
     K getRightMostKey();
@@ -184,7 +184,7 @@
     /**
      * Finds the leftmost element in this page. If the page is a node, it will go
      * down in the leftmost children to recursively find the leftmost element.
-     * 
+     *
      * @return The leftmost element in the tree
      * @throws IOException If we have an error while trying to access the page
      */
@@ -194,7 +194,7 @@
     /**
      * Finds the rightmost element in this page. If the page is a node, it will go
      * down in the rightmost children to recursively find the rightmost element.
-     * 
+     *
      * @return The rightmost element in the tree
      * @throws IOException If we have an error while trying to access the page
      */
@@ -240,8 +240,8 @@
      * <li>'h' will return -4</li>
      * <li>'i' will return 4</li>
      * </ul>
-     * 
-     * 
+     *
+     *
      * @param key The key to find
      * @return The position in the page.
      */
@@ -250,7 +250,7 @@
 
     /**
      * Checks if the given key exists.
-     *  
+     *
      * @param key The key we are looking at
      * @return true if the key is present, false otherwise
      * @throws IOException If we have an error while trying to access the page
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageIO.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageIO.java
index a395566..dbff0ed 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageIO.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageIO.java
@@ -34,25 +34,25 @@
  * Here is the logical structure of a PageIO :
  * <pre>
  * For a first page :
- * 
+ *
  * +----------+------+----------------------+
  * | nextPage | size | XXXXXXXXXXXXXXXXXXXX |
  * +----------+------+----------------------+
- * 
+ *
  * for any page but the first :
- * 
+ *
  * +----------+-----------------------------+
  * | nextPage | XXXXXXXXXXXXXXXXXXXXXXXXXXX |
  * +----------+-----------------------------+
- * 
+ *
  * for the last page :
  * +----------+-----------------------------+
  * |    -1    | XXXXXXXXXXXXXXXXXXXXXXXXXXX |
  * +----------+-----------------------------+
- * 
+ *
  * In any case, the page length is always PageSize.
  * </pre>
- *  
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 /* No qualifier*/class PageIO
@@ -70,7 +70,7 @@
     private long offset;
 
 
-    /** 
+    /**
      * A default constructor for a PageIO
      */
     /* no qualifier */PageIO()
@@ -81,7 +81,7 @@
     }
 
 
-    /** 
+    /**
      * A constructor for a PageIO when we know the offset of this page on disk
      */
     /* no qualifier */PageIO( long offset )
@@ -179,6 +179,45 @@
     }
 
 
+    /* no qualifier */PageIO copy( PageIO copy )
+    {
+        // The data
+        if ( data.isDirect() )
+        {
+            copy.data = ByteBuffer.allocateDirect( data.capacity() );
+        }
+        else
+        {
+            copy.data = ByteBuffer.allocate( data.capacity() );
+        }
+
+        // Save the original buffer position and limit
+        int start = data.position();
+        int limit = data.limit();
+
+        // The data is extended to get all the bytes in it
+        data.position( 0 );
+        data.limit( data.capacity() );
+
+        // Copy the data
+        copy.data.put( data );
+
+        // Restore the original buffer to the initial position and limit
+        data.position( start );
+        data.limit( limit );
+
+        // Set those position and limit in the copied buffer
+        copy.data.position( start );
+        copy.data.limit( limit );
+
+        // The size
+        copy.size = size;
+
+        // The offset and next page pointers are not copied.
+        return copy;
+    }
+
+
     /**
      * @see Object#toString()
      */
@@ -186,7 +225,7 @@
     {
         StringBuilder sb = new StringBuilder();
 
-        sb.append( "PageIO[offset:" ).append( offset );
+        sb.append( "PageIO[offset:0x" ).append( Long.toHexString( offset ) );
 
         if ( size != -1 )
         {
@@ -195,7 +234,7 @@
 
         if ( nextPage != -1L )
         {
-            sb.append( ", next:" ).append( nextPage );
+            sb.append( ", next:0x" ).append( Long.toHexString( nextPage ) );
         }
 
         sb.append( "]" );
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java
index dbb6a51..e5c9c2d 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java
@@ -24,9 +24,7 @@
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
-import java.util.Map;
 import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.locks.ReentrantLock;
 
 import net.sf.ehcache.Cache;
 import net.sf.ehcache.Status;
@@ -50,47 +48,44 @@
     /** The LoggerFactory used by this class */
     protected static final Logger LOG = LoggerFactory.getLogger( PersistedBTree.class );
 
-    /** The RecordManager if the BTree is managed */
-    private RecordManager recordManager;
+    protected static final Logger LOG_PAGES = LoggerFactory.getLogger( "LOG_PAGES" );
 
-    /** The cache associated with this BTree */
+    /** The cache associated with this B-tree */
     protected Cache cache;
 
     /** The default number of pages to keep in memory */
-    static final int DEFAULT_CACHE_SIZE = 1000;
+    public static final int DEFAULT_CACHE_SIZE = 1000;
 
     /** The cache size, default to 1000 elements */
     protected int cacheSize = DEFAULT_CACHE_SIZE;
 
-    /** A flag indicating if this BTree is a Sub BTree */
-    private boolean isSubBtree = false;
-
-    /** The number of stored Values before we switch to a BTree */
+    /** The number of stored Values before we switch to a B-tree */
     private static final int DEFAULT_VALUE_THRESHOLD_UP = 8;
 
     /** The number of stored Values before we switch back to an array */
     private static final int DEFAULT_VALUE_THRESHOLD_LOW = 1;
 
-    /** The configuration for the array <-> BTree switch */
+    /** The configuration for the array <-> B-tree switch */
     /*No qualifier*/static int valueThresholdUp = DEFAULT_VALUE_THRESHOLD_UP;
     /*No qualifier*/static int valueThresholdLow = DEFAULT_VALUE_THRESHOLD_LOW;
 
-    /** A lock to protect the creation of the transaction */
-    protected ReentrantLock createTransaction = new ReentrantLock();
-
+    /** The BtreeInfo offset */
+    private long btreeInfoOffset;
+    
+    /** The internal recordManager */
+    private RecordManager recordManager;
 
     /**
      * Creates a new BTree, with no initialization.
      */
     /* no qualifier */PersistedBTree()
     {
-        btreeHeader = new BTreeHeader();
         setType( BTreeTypeEnum.PERSISTED );
     }
 
 
     /**
-     * Creates a new persisted BTree using the BTreeConfiguration to initialize the
+     * Creates a new persisted B-tree using the BTreeConfiguration to initialize the
      * BTree
      *
      * @param configuration The configuration to use
@@ -105,22 +100,16 @@
             throw new IllegalArgumentException( "BTree name cannot be null" );
         }
 
-        btreeHeader = new BTreeHeader();
-        btreeHeader.setName( name );
-        btreeHeader.setPageSize( configuration.getPageSize() );
-        isSubBtree = configuration.isSubBtree();
-
-        keySerializer = configuration.getKeySerializer();
-        btreeHeader.setKeySerializerFQCN( keySerializer.getClass().getName() );
-
-        valueSerializer = configuration.getValueSerializer();
-        btreeHeader.setValueSerializerFQCN( valueSerializer.getClass().getName() );
+        setName( name );
+        setPageSize( configuration.getPageSize() );
+        setKeySerializer( configuration.getKeySerializer() );
+        setValueSerializer( configuration.getValueSerializer() );
+        setAllowDuplicates( configuration.isAllowDuplicates() );
+        setType( configuration.getBtreeType() );
 
         readTimeOut = configuration.getReadTimeOut();
         writeBufferSize = configuration.getWriteBufferSize();
-        btreeHeader.setAllowDuplicates( configuration.isAllowDuplicates() );
         cacheSize = configuration.getCacheSize();
-        setType( BTreeTypeEnum.PERSISTED );
 
         if ( keySerializer.getComparator() == null )
         {
@@ -129,18 +118,35 @@
 
         // Create the first root page, with revision 0L. It will be empty
         // and increment the revision at the same time
-        rootPage = new PersistedLeaf<K, V>( this );
+        Page<K, V> rootPage = new PersistedLeaf<K, V>( this );
 
-        if ( isSubBtree )
+        // Create a B-tree header, and initialize it
+        BTreeHeader<K, V> btreeHeader = new BTreeHeader<K, V>();
+        btreeHeader.setRootPage( rootPage );
+        btreeHeader.setBtree( this );
+
+        switch ( btreeType )
         {
-            // The subBTree inherit its cache from its parent BTree
-            this.cache = ( ( PersistedBTree<K, V> ) configuration.getParentBTree() ).getCache();
-            this.writeLock = ( ( PersistedBTree<K, V> ) configuration.getParentBTree() ).getWriteLock();
-            readTransactions = new ConcurrentLinkedQueue<ReadTransaction<K, V>>();
-        }
+            case BTREE_OF_BTREES :
+            case COPIED_PAGES_BTREE :
+                // We will create a new cache and a new readTransactions map 
+                init( null );
+                currentBtreeHeader = btreeHeader;
+                break;
 
-        // Now, initialize the BTree
-        init();
+            case PERSISTED_SUB :
+                init( ( PersistedBTree<K, V> ) configuration.getParentBTree() );
+                btreeRevisions.put( 0L, btreeHeader );
+                currentBtreeHeader = btreeHeader;
+                break;
+                
+            default :
+                // We will create a new cache and a new readTransactions map 
+                init( null );
+                btreeRevisions.put( 0L, btreeHeader );
+                currentBtreeHeader = btreeHeader;
+                break;
+        }
     }
 
 
@@ -149,17 +155,15 @@
      *
      * @throws IOException If we get some exception while initializing the BTree
      */
-    public void init()
+    public void init( BTree<K, V> parentBTree )
     {
-        if ( !isSubBtree )
+        if ( parentBTree == null )
         {
             // This is not a subBtree, we have to initialize the cache
 
             // Create the queue containing the pending read transactions
             readTransactions = new ConcurrentLinkedQueue<ReadTransaction<K, V>>();
 
-            writeLock = new ReentrantLock();
-
             // Initialize the caches
             CacheConfiguration cacheConfiguration = new CacheConfiguration();
             cacheConfiguration.setName( "pages" );
@@ -172,6 +176,11 @@
             cache = new Cache( cacheConfiguration );
             cache.initialise();
         }
+        else
+        {
+            this.cache = ((PersistedBTree<K, V>)parentBTree).getCache();
+            this.readTransactions = ((PersistedBTree<K, V>)parentBTree).getReadTransactions();
+        }
 
         // Initialize the txnManager thread
         //FIXME we should NOT create a new transaction manager thread for each BTree
@@ -191,15 +200,6 @@
     /**
      * Return the cache we use in this BTree
      */
-    /* No qualifier */ReentrantLock getWriteLock()
-    {
-        return writeLock;
-    }
-
-
-    /**
-     * Return the cache we use in this BTree
-     */
     /* No qualifier */ConcurrentLinkedQueue<ReadTransaction<K, V>> getReadTransactions()
     {
         return readTransactions;
@@ -222,8 +222,6 @@
         }
 
         cache.dispose();
-
-        rootPage = null;
     }
 
 
@@ -232,16 +230,16 @@
      */
     /* No qualifier*/long getBtreeOffset()
     {
-        return btreeHeader.getBTreeOffset();
+        return getBTreeHeader( getName() ).getBTreeHeaderOffset();
     }
 
 
     /**
-     * @param btreeOffset the btreeOffset to set
+     * @param btreeOffset the B-tree header Offset to set
      */
-    /* No qualifier*/void setBtreeOffset( long btreeOffset )
+    /* No qualifier*/void setBtreeHeaderOffset( long btreeHeaderOffset )
     {
-        btreeHeader.setBTreeOffset( btreeOffset );
+        getBTreeHeader( getName() ).setBTreeHeaderOffset( btreeHeaderOffset );
     }
 
 
@@ -250,41 +248,14 @@
      */
     /* No qualifier*/long getRootPageOffset()
     {
-        return btreeHeader.getRootPageOffset();
-    }
-
-
-    /**
-     * @param rootPageOffset the rootPageOffset to set
-     */
-    /* No qualifier*/void setRootPageOffset( long rootPageOffset )
-    {
-        btreeHeader.setRootPageOffset( rootPageOffset );
-    }
-
-
-    /**
-     * @return the nextBTreeOffset
-     */
-    /* No qualifier*/long getNextBTreeOffset()
-    {
-        return btreeHeader.getNextBTreeOffset();
-    }
-
-
-    /**
-     * @param nextBTreeOffset the nextBTreeOffset to set
-     */
-    /* No qualifier*/void setNextBTreeOffset( long nextBTreeOffset )
-    {
-        btreeHeader.setNextBTreeOffset( nextBTreeOffset );
+        return getBTreeHeader( getName() ).getRootPageOffset();
     }
 
 
     /**
      * Gets the RecordManager for a managed BTree
      *
-     * @return The recordManager if the BTree is managed
+     * @return The recordManager if the B-tree is managed
      */
     /* No qualifier */RecordManager getRecordManager()
     {
@@ -299,6 +270,8 @@
      */
     /* No qualifier */void setRecordManager( RecordManager recordManager )
     {
+        // The RecordManager is also the TransactionManager
+        transactionManager = recordManager;
         this.recordManager = recordManager;
     }
 
@@ -315,85 +288,162 @@
      * @return
      * @throws IOException
      */
-    protected Tuple<K, V> delete( K key, V value, long revision ) throws IOException
+    /* no qualifier */ Tuple<K, V> delete( K key, V value, long revision ) throws IOException
     {
-        writeLock.lock();
+        // We have to start a new transaction, which will be committed or rollbacked
+        // locally. This will duplicate the current BtreeHeader during this phase.
+        if ( revision == -1L )
+        {
+            revision = currentRevision.get() + 1;
+        }
 
         try
         {
-            // If the key exists, the existing value will be replaced. We store it
-            // to return it to the caller.
-            Tuple<K, V> tuple = null;
-
             // Try to delete the entry starting from the root page. Here, the root
             // page may be either a Node or a Leaf
-            DeleteResult<K, V> result = rootPage.delete( revision, key, value, null, -1 );
+            DeleteResult<K, V> result = processDelete( key, value, revision );
 
+            // Check that we have found the element to delete
             if ( result instanceof NotPresentResult )
             {
-                // Key not found.
+                // We haven't found the element in the B-tree, just get out
+                // without updating the recordManager
+
                 return null;
             }
 
-            // Keep the oldRootPage so that we can later access it
-            Page<K, V> oldRootPage = rootPage;
+            // The element was found, and removed
+            AbstractDeleteResult<K, V> deleteResult = ( AbstractDeleteResult<K, V> ) result;
 
-            if ( result instanceof RemoveResult )
-            {
-                // The element was found, and removed
-                RemoveResult<K, V> removeResult = ( RemoveResult<K, V> ) result;
+            Tuple<K, V> tuple = deleteResult.getRemovedElement();
 
-                Page<K, V> modifiedPage = removeResult.getModifiedPage();
-
-                // Write the modified page on disk
-                // Note that we don't use the holder, the new root page will
-                // remain in memory.
-                PageHolder<K, V> holder = writePage( modifiedPage, revision );
-
-                // Store the offset on disk in the page in memory
-                ( ( AbstractPage<K, V> ) modifiedPage ).setOffset( ( ( PersistedPageHolder<K, V> ) holder )
-                    .getOffset() );
-
-                // Store the last offset on disk in the page in memory
-                ( ( AbstractPage<K, V> ) modifiedPage )
-                    .setLastOffset( ( ( PersistedPageHolder<K, V> ) holder )
-                        .getLastOffset() );
-
-                // This is a new root
-                rootPage = modifiedPage;
-                tuple = removeResult.getRemovedElement();
-            }
-
-            // Decrease the number of elements in the current tree if the deletion is successful
-            if ( tuple != null )
-            {
-                btreeHeader.decrementNbElems();
-
-                // We have to update the rootPage on disk
-                // Update the BTree header now
-                recordManager.updateBtreeHeader( this, ( ( AbstractPage<K, V> ) rootPage ).getOffset() );
-            }
-
-            recordManager.addFreePages( this, result.getCopiedPages() );
-
+            // If the B-tree is managed, we have to update the rootPage on disk
             // Update the RecordManager header
-            recordManager.updateRecordManagerHeader();
-
-            // Store the created rootPage into the revision BTree, this will be stored in RecordManager only if revisions are set to keep
-            recordManager.storeRootPage( this, rootPage );
 
             // Return the value we have found if it was modified
             return tuple;
         }
-        finally
+        catch ( IOException ioe )
         {
-            // See above
-            writeLock.unlock();
+            // if we've got an error, we have to rollback
+            throw ioe;
         }
     }
 
 
     /**
+     * Insert the tuple into the B-tree rootPage, get back the new rootPage
+     */
+    private DeleteResult<K, V> processDelete( K key, V value, long revision ) throws IOException
+    {
+        // Get the current B-tree header, and delete the value from it
+        BTreeHeader<K, V> btreeHeader = getBTreeHeader( getName() );
+
+        // Try to delete the entry starting from the root page. Here, the root
+        // page may be either a Node or a Leaf
+        DeleteResult<K, V> result = btreeHeader.getRootPage().delete( key, value, revision);
+
+        if ( result instanceof NotPresentResult )
+        {
+            // Key not found.
+            return result;
+        }
+
+        // Create a new BTreeHeader
+        BTreeHeader<K, V> newBtreeHeader = btreeHeader.copy();
+
+        // Inject the old B-tree header into the pages to be freed
+        // if we are deleting an element from a management BTree
+        if ( ( btreeType == BTreeTypeEnum.BTREE_OF_BTREES ) || ( btreeType == BTreeTypeEnum.COPIED_PAGES_BTREE ) )
+        {
+            PageIO[] pageIos = recordManager.readPageIOs( btreeHeader.getBTreeHeaderOffset(), -1L );
+
+            for ( PageIO pageIo : pageIos )
+            {
+                recordManager.freedPages.add( pageIo );
+            }
+        }
+
+        // The element was found, and removed
+        AbstractDeleteResult<K, V> removeResult = ( AbstractDeleteResult<K, V> ) result;
+
+        // This is a new root
+        Page<K, V> newRootPage = removeResult.getModifiedPage();
+
+        // Write the modified page on disk
+        // Note that we don't use the holder, the new root page will
+        // remain in memory.
+        PageHolder<K, V> holder = writePage( newRootPage, revision );
+
+        // Decrease the number of elements in the current tree
+        newBtreeHeader.decrementNbElems();
+        newBtreeHeader.setRootPage( newRootPage );
+        newBtreeHeader.setRevision( revision );
+
+        // Write down the data on disk
+        long newBtreeHeaderOffset = recordManager.writeBtreeHeader( this, newBtreeHeader );
+
+
+        // Update the B-tree of B-trees with this new offset, if we are not already doing so
+        switch ( btreeType )
+        {
+            case PERSISTED :
+                // We have a new B-tree header to inject into the B-tree of btrees
+                recordManager.addInBtreeOfBtrees( getName(), revision, newBtreeHeaderOffset );
+
+                recordManager.addInCopiedPagesBtree( getName(), revision, result.getCopiedPages() );
+
+                // Store the new revision
+                storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
+
+                break;
+                
+            case PERSISTED_SUB :
+                // Sub-B-trees are only updating the CopiedPage B-tree
+                recordManager.addInCopiedPagesBtree( getName(), revision, result.getCopiedPages() );
+                
+                //btreeRevisions.put( revision, newBtreeHeader );
+
+                currentRevision.set( revision );
+
+
+                break;
+
+            case BTREE_OF_BTREES :
+                // The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
+                recordManager.updateRecordManagerHeader( newBtreeHeaderOffset, -1L );
+
+                // We can free the copied pages
+                recordManager.freePages( this, revision, result.getCopiedPages() );
+
+                // Store the new revision
+                storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
+
+                break;
+
+            case COPIED_PAGES_BTREE :
+                // The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
+                recordManager.updateRecordManagerHeader( -1L, newBtreeHeaderOffset );
+
+                // We can free the copied pages
+                recordManager.freePages( this, revision, result.getCopiedPages() );
+
+                // Store the new revision
+                storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
+
+                break;
+
+            default:
+                // Nothing to do for sub-btrees
+                break;
+        }
+
+        // Return the value we have found if it was modified
+        return result;
+    }
+
+
+    /**
      * Insert an entry in the BTree.
      * <p>
      * We will replace the value if the provided key already exists in the
@@ -408,36 +458,79 @@
      */
     /* no qualifier */InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
     {
-        if ( key == null )
+        // We have to start a new transaction, which will be committed or rollbacked
+        // locally. This will duplicate the current BtreeHeader during this phase.
+        if ( revision == -1L )
         {
-            throw new IllegalArgumentException( "Key must not be null" );
+            revision = currentRevision.get() + 1;
         }
 
-        // If the key exists, the existing value will be replaced. We store it
-        // to return it to the caller.
-        V modifiedValue = null;
+        try
+        {
+            // Try to insert the new value in the tree at the right place,
+            // starting from the root page. Here, the root page may be either
+            // a Node or a Leaf
+            InsertResult<K, V> result = processInsert( key, value, revision );
 
-        // Try to insert the new value in the tree at the right place,
-        // starting from the root page. Here, the root page may be either
-        // a Node or a Leaf
-        InsertResult<K, V> result = rootPage.insert( revision, key, value );
+            // Return the value we have found if it was modified
+            return result;
+        }
+        catch ( IOException ioe )
+        {
+            throw ioe;
+        }
+    }
+
+    
+    private BTreeHeader<K, V> getBTreeHeader( String name )
+    {
+        if ( btreeType == BTreeTypeEnum.PERSISTED_SUB )
+        {
+            return getBtreeHeader();
+        }
+        
+        BTreeHeader<K, V> btreeHeader = recordManager.getBTreeHeader( getName() );
+
+        return btreeHeader;
+    }
+
+    /**
+     * Insert the tuple into the B-tree rootPage, get back the new rootPage
+     */
+    private InsertResult<K, V> processInsert( K key, V value, long revision ) throws IOException
+    {
+        // Get the current B-tree header, and insert the value into it
+        BTreeHeader<K, V> btreeHeader = getBTreeHeader( getName() );
+        InsertResult<K, V> result = btreeHeader.getRootPage().insert( key, value, revision );
+
+        // Create a new BTreeHeader
+        BTreeHeader<K, V> newBtreeHeader = btreeHeader.copy();
+
+        // Inject the old B-tree header into the pages to be freed
+        // if we are inserting an element in a management BTree
+        if ( ( btreeType == BTreeTypeEnum.BTREE_OF_BTREES ) || ( btreeType == BTreeTypeEnum.COPIED_PAGES_BTREE ) )
+        {
+            PageIO[] pageIos = recordManager.readPageIOs( btreeHeader.getBTreeHeaderOffset(), -1L );
+
+            for ( PageIO pageIo : pageIos )
+            {
+                recordManager.freedPages.add( pageIo );
+            }
+        }
+
+        Page<K, V> newRootPage;
 
         if ( result instanceof ModifyResult )
         {
             ModifyResult<K, V> modifyResult = ( ( ModifyResult<K, V> ) result );
 
-            Page<K, V> modifiedPage = modifyResult.getModifiedPage();
+            newRootPage = modifyResult.getModifiedPage();
 
-            // Write the modified page on disk
-            // Note that we don't use the holder, the new root page will
-            // remain in memory.
-            writePage( modifiedPage, revision );
-
-            // The root has just been modified, we haven't split it
-            // Get it and make it the current root page
-            rootPage = modifiedPage;
-
-            modifiedValue = modifyResult.getModifiedValue();
+            // Increment the counter if we have inserted a new value
+            if ( modifyResult.getModifiedValue() == null )
+            {
+                newBtreeHeader.incrementNbElems();
+            }
         }
         else
         {
@@ -448,9 +541,8 @@
             K pivot = splitResult.getPivot();
             Page<K, V> leftPage = splitResult.getLeftPage();
             Page<K, V> rightPage = splitResult.getRightPage();
-            Page<K, V> newRootPage = null;
 
-            // If the BTree is managed, we have to write the two pages that were created
+            // If the B-tree is managed, we have to write the two pages that were created
             // and to keep a track of the two offsets for the upper node
             PageHolder<K, V> holderLeft = writePage( leftPage, revision );
 
@@ -459,41 +551,81 @@
             // Create the new rootPage
             newRootPage = new PersistedNode<K, V>( this, revision, pivot, holderLeft, holderRight );
 
-            // If the BTree is managed, we now have to write the page on disk
-            // and to add this page to the list of modified pages
-            PageHolder<K, V> holder = writePage( newRootPage, revision );
-
-            rootPage = newRootPage;
+            // Always increment the counter : we have added a new value
+            newBtreeHeader.incrementNbElems();
         }
 
-        // Increase the number of element in the current tree if the insertion is successful
-        // and does not replace an element
-        if ( modifiedValue == null )
+        // Write the new root page on disk
+        LOG_PAGES.debug( "Writing the new rootPage revision {} for {}", revision, name );
+        writePage( newRootPage, revision );
+
+        // Update the new B-tree header
+        newBtreeHeader.setRootPage( newRootPage );
+        newBtreeHeader.setRevision( revision );
+
+        // Write down the data on disk
+        long newBtreeHeaderOffset = recordManager.writeBtreeHeader( this, newBtreeHeader );
+
+        // Update the B-tree of B-trees with this new offset, if we are not already doing so
+        switch ( btreeType )
         {
-            btreeHeader.incrementNbElems();
+            case PERSISTED :
+                // We have a new B-tree header to inject into the B-tree of btrees
+                recordManager.addInBtreeOfBtrees( getName(), revision, newBtreeHeaderOffset );
+
+                recordManager.addInCopiedPagesBtree( getName(), revision, result.getCopiedPages() );
+
+                // Store the new revision
+                storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
+
+                break;
+
+            case PERSISTED_SUB :
+                // Sub-B-trees are only updating the CopiedPage B-tree
+                recordManager.addInCopiedPagesBtree( getName(), revision, result.getCopiedPages() );
+                
+                //btreeRevisions.put( revision, newBtreeHeader );
+
+                // Store the new revision
+                storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
+
+                currentRevision.set( revision );
+
+                break;
+
+            case BTREE_OF_BTREES :
+                // The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
+                recordManager.updateRecordManagerHeader( newBtreeHeaderOffset, -1L );
+
+                // We can free the copied pages
+                recordManager.freePages( this, revision, result.getCopiedPages() );
+
+                // Store the new revision
+                storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
+
+                break;
+
+            case COPIED_PAGES_BTREE :
+                // The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
+                recordManager.updateRecordManagerHeader( -1L, newBtreeHeaderOffset );
+
+                // We can free the copied pages
+                recordManager.freePages( this, revision, result.getCopiedPages() );
+
+                // Store the new revision
+                storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
+
+                break;
+
+            default:
+                // Nothing to do for sub-btrees
+                break;
         }
 
-        // If the BTree is managed, we have to update the rootPage on disk
-        // Update the RecordManager header
-        if ( ( writeTransaction == null ) || !writeTransaction.isStarted() )
-        {
-            recordManager.updateRecordManagerHeader();
-
-            // Update the BTree header now
-            recordManager.updateBtreeHeader( this, ( ( AbstractPage<K, V> ) rootPage ).getOffset() );
-
-            // Moved the free pages into the list of free pages
-            recordManager.addFreePages( this, result.getCopiedPages() );
-
-            // Store the created rootPage into the revision BTree, this will be stored in RecordManager only if revisions are set to keep
-            recordManager.storeRootPage( this, rootPage );
-        }
-
-        // Return the value we have found if it was modified
+        // Get the new root page and make it the current root page
         return result;
     }
 
-
     /**
      * Write the data in the ByteBuffer, and eventually on disk if needed.
      *
@@ -541,21 +673,9 @@
      */
     private PageHolder<K, V> writePage( Page<K, V> modifiedPage, long revision ) throws IOException
     {
-        if ( ( writeTransaction != null ) && writeTransaction.isStarted() )
-        {
-            Map<Page<?, ?>, BTree<?, ?>> pendingPages = recordManager.getPendingPages();
-            pendingPages.put( modifiedPage, this );
+        PageHolder<K, V> pageHolder = recordManager.writePage( this, modifiedPage, revision );
 
-            PageHolder<K, V> pageHolder = new PageHolder<K, V>( this, modifiedPage );
-
-            return pageHolder;
-        }
-        else
-        {
-            PageHolder<K, V> pageHolder = recordManager.writePage( this, modifiedPage, revision );
-
-            return pageHolder;
-        }
+        return pageHolder;
     }
 
     /**
@@ -573,60 +693,76 @@
 
 
     /**
-     * Starts a transaction
+     * Get the current rootPage
+     *
+     * @return The rootPage
      */
-    public void beginTransaction()
+    public Page<K, V> getRootPage()
     {
-        createTransaction.lock();
+        return getBTreeHeader( getName() ).getRootPage();
+    }
 
-        if ( writeTransaction == null )
-        {
-            writeTransaction = new WriteTransaction( recordManager );
-        }
 
-        createTransaction.unlock();
-
-        writeTransaction.start();
+    /* no qualifier */void setRootPage( Page<K, V> root )
+    {
+        getBTreeHeader( getName() ).setRootPage( root );
     }
 
 
     /**
-     * Commits a transaction
+     * @return the btreeInfoOffset
      */
-    public void commit()
+    public long getBtreeInfoOffset()
     {
-        createTransaction.lock();
-
-        if ( writeTransaction == null )
-        {
-            writeTransaction = new WriteTransaction( recordManager );
-        }
-
-        createTransaction.unlock();
-
-        writeTransaction.commit();
+        return btreeInfoOffset;
     }
 
 
     /**
-     * Rollback a transaction
+     * @param btreeInfoOffset the btreeInfoOffset to set
      */
-    public void rollback()
+    public void setBtreeInfoOffset( long btreeInfoOffset )
     {
-        createTransaction.lock();
-
-        if ( writeTransaction == null )
-        {
-            writeTransaction = new WriteTransaction( recordManager );
-        }
-
-        createTransaction.unlock();
-
-        writeTransaction.rollback();
+        this.btreeInfoOffset = btreeInfoOffset;
     }
 
 
+    /**
+     * {@inheritDoc}
+     */
+    protected ReadTransaction<K, V> beginReadTransaction()
+    {
+        BTreeHeader<K, V> btreeHeader = getBTreeHeader( getName() );
 
+        ReadTransaction<K, V> readTransaction = new ReadTransaction<K, V>( recordManager, btreeHeader, readTransactions );
+
+        readTransactions.add( readTransaction );
+
+        return readTransaction;
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    protected ReadTransaction<K, V> beginReadTransaction( long revision )
+    {
+        BTreeHeader<K, V> btreeHeader = getBtreeHeader( revision );
+
+        if ( btreeHeader != null )
+        {
+            ReadTransaction<K, V> readTransaction = new ReadTransaction<K, V>(  recordManager, btreeHeader, readTransactions );
+
+            readTransactions.add( readTransaction );
+
+            return readTransaction;
+        }
+        else
+        {
+            return null;
+        }
+    }
+    
 
     /**
      * @see Object#toString()
@@ -636,12 +772,12 @@
         StringBuilder sb = new StringBuilder();
 
         sb.append( "Managed BTree" );
-        sb.append( "[" ).append( btreeHeader.getName() ).append( "]" );
-        sb.append( "( pageSize:" ).append( btreeHeader.getPageSize() );
+        sb.append( "[" ).append( getName() ).append( "]" );
+        sb.append( "( pageSize:" ).append( getPageSize() );
 
-        if ( rootPage != null )
+        if ( getBTreeHeader( getName() ).getRootPage() != null )
         {
-            sb.append( ", nbEntries:" ).append( btreeHeader.getNbElems() );
+            sb.append( ", nbEntries:" ).append( getBTreeHeader( getName() ).getNbElems() );
         }
         else
         {
@@ -659,10 +795,10 @@
             sb.append( keySerializer.getComparator().getClass().getSimpleName() );
         }
 
-        sb.append( ", DuplicatesAllowed: " ).append( btreeHeader.isAllowDuplicates() );
+        sb.append( ", DuplicatesAllowed: " ).append( isAllowDuplicates() );
 
         sb.append( ") : \n" );
-        sb.append( rootPage.dumpPage( "" ) );
+        sb.append( getBTreeHeader( getName() ).getRootPage().dumpPage( "" ) );
 
         return sb.toString();
     }
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilder.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilder.java
index 0db1a7a..d7474ea 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilder.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilder.java
@@ -32,7 +32,7 @@
 
 
 /**
- * A BTree builder that builds a tree from the bottom.
+ * A B-tree builder that builds a tree from the bottom.
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
@@ -138,7 +138,7 @@
 
         rm.updateBtreeHeader( btree, ( ( AbstractPage<K, V> ) rootPage ).getOffset() );
 
-        rm.addFreePages( btree, Arrays.asList( btree.getRootPage() ) );
+        rm.freePages( btree, btree.getRootPage().getRevision(), Arrays.asList( btree.getRootPage() ) );
 
         ( ( AbstractBTree<K, V> ) btree ).setRootPage( rootPage );
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeConfiguration.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeConfiguration.java
index 3fd4d0a..20c7020 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeConfiguration.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeConfiguration.java
@@ -25,11 +25,11 @@
 
 /**
  * The B+Tree Configuration. This class can be used to store all the configurable
- * parameters used by the BTree class
- * 
+ * parameters used by the B-tree class
+ *
  * @param <K> The type for the keys
  * @param <V> The type for the stored values
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class PersistedBTreeConfiguration<K, V>
@@ -40,23 +40,23 @@
     /** The size of the buffer used to write data in disk */
     private int writeBufferSize = BTree.DEFAULT_WRITE_BUFFER_SIZE;
 
-    /** The Key and Value serializer used for this tree. If none is provided, 
-     * the BTree will deduce the serializer to use from the generic type, and
+    /** The Key and Value serializer used for this tree. If none is provided,
+     * the B-tree will deduce the serializer to use from the generic type, and
      * use the default Java serialization  */
     private ElementSerializer<K> keySerializer;
     private ElementSerializer<V> valueSerializer;
 
-    /** The BTree name */
+    /** The B-tree name */
     private String name;
 
-    /** The path where the BTree file will be stored. Default to the local 
+    /** The path where the B-tree file will be stored. Default to the local
      * temporary directory.
      */
     private String filePath;
 
-    /** 
+    /**
      * The maximum delay to wait before a revision is considered as unused.
-     * This delay is necessary so that a read that does not ends does not 
+     * This delay is necessary so that a read that does not ends does not
      * hold a revision in memory forever.
      * The default value is 10000 (10 seconds). If the value is 0 or below,
      * the delay is considered as infinite
@@ -66,13 +66,13 @@
     /** Flag to enable duplicate key support */
     private boolean allowDuplicates;
 
-    /** A flag set when the BTree is a sub btree */
-    private boolean isSubBtree = false;
+    /** The B-tree type */
+    private BTreeTypeEnum btreeType = BTreeTypeEnum.PERSISTED;
 
     /** The cache size, if it's <= 0, we don't have cache */
     private int cacheSize;
 
-    /** The inherited BTree if we create a sub BTree */
+    /** The inherited B-tree if we create a sub B-tree */
     private BTree<?, V> parentBTree;
 
 
@@ -224,10 +224,10 @@
 
     /**
      * enable duplicate key support
-     * 
+     *
      * @param allowDuplicates
-     * @throws IllegalStateException if the btree was already initialized or when tried to turn off duplicate suport on
-     * an existing btree containing duplicate keys
+     * @throws IllegalStateException if the B-tree was already initialized or when tried to turn off duplicate suport on
+     * an existing B-tree containing duplicate keys
      */
     public void setAllowDuplicates( boolean allowDuplicates )
     {
@@ -272,19 +272,19 @@
 
 
     /**
-     * @return True if this is a sub btree, false otherwise
+     * @return The BtreeType for this Btree
      */
-    public boolean isSubBtree()
+    public BTreeTypeEnum getBtreeType()
     {
-        return isSubBtree;
+        return btreeType;
     }
 
 
     /**
-     * @param isSubBtree True if the BTree will be a sub btree, false otherwise
+     * @param btreeType The BtreeType
      */
-    public void setSubBtree( boolean isSubBtree )
+    public void setBtreeType( BTreeTypeEnum btreeType )
     {
-        this.isSubBtree = isSubBtree;
+        this.btreeType = btreeType;
     }
 }
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedLeaf.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedLeaf.java
index 505bc43..013fd67 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedLeaf.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedLeaf.java
@@ -71,7 +71,7 @@
     /**
      * {@inheritDoc}
      */
-    public InsertResult<K, V> insert( long revision, K key, V value ) throws IOException
+    public InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
     {
         // Find the key into this leaf
         int pos = findPos( key );
@@ -116,7 +116,7 @@
      * {@inheritDoc}
      */
     @SuppressWarnings("unchecked")
-    public DeleteResult<K, V> delete( long revision, K key, V value, Page<K, V> parent, int parentPos )
+    /* no qualifier */ DeleteResult<K, V> delete( K key, V value, long revision, Page<K, V> parent, int parentPos )
         throws IOException
     {
         // Check that the leaf is not empty
@@ -519,7 +519,7 @@
         }
         else
         {
-            throw KEY_NOT_FOUND_EXCEPTION;
+            throw KeyNotFoundException.INSTANCE;
         }
     }
 
@@ -561,7 +561,7 @@
         }
         else
         {
-            throw KEY_NOT_FOUND_EXCEPTION;
+            throw KeyNotFoundException.INSTANCE;
         }
     }
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java
index 8526862..52711c4 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java
@@ -120,7 +120,7 @@
     /**
      * {@inheritDoc}
      */
-    public InsertResult<K, V> insert( long revision, K key, V value ) throws IOException
+    public InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
     {
         // Find the key into this leaf
         int pos = findPos( key );
@@ -136,7 +136,7 @@
         Page<K, V> child = children[pos].getValue();
 
         // and insert the <K, V> into this child
-        InsertResult<K, V> result = child.insert( revision, key, value );
+        InsertResult<K, V> result = child.insert( key, value, revision );
 
         // Ok, now, we have injected the <K, V> tuple down the tree. Let's check
         // the result to see if we have to split the current page
@@ -567,7 +567,7 @@
     /**
      * {@inheritDoc}
      */
-    public DeleteResult<K, V> delete( long revision, K key, V value, Page<K, V> parent, int parentPos )
+    /* no qualifier */ DeleteResult<K, V> delete( K key, V value, long revision, Page<K, V> parent, int parentPos )
         throws IOException
     {
         // We first try to delete the element from the child it belongs to
@@ -582,12 +582,12 @@
         {
             index = -( pos + 1 );
             child = children[-pos].getValue();
-            deleteResult = child.delete( revision, key, value, this, -pos );
+            deleteResult = ((AbstractPage<K, V>)child).delete( key, value, revision, this, -pos );
         }
         else
         {
             child = children[pos].getValue();
-            deleteResult = child.delete( revision, key, value, this, pos );
+            deleteResult = ((AbstractPage<K, V>)child).delete( key, value, revision, this, pos );
         }
 
         // If the key is not present in the tree, we simply return
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedValueHolder.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedValueHolder.java
index 1e819cc..794d51f 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedValueHolder.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedValueHolder.java
@@ -28,6 +28,7 @@
 import org.apache.directory.mavibot.btree.exception.BTreeAlreadyCreatedException;
 import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
 import org.apache.directory.mavibot.btree.exception.BTreeCreationException;
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.IntSerializer;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
 
@@ -82,7 +83,7 @@
 
     /**
      * Creates a new instance of a ValueHolder, containing Values. This constructor is called
-     * whe we need to create a new ValueHolder with deserialized values.
+     * when we need to create a new ValueHolder with deserialized values.
      *
      * @param parentBtree The parent BTree
      * @param values The Values stored in the ValueHolder
@@ -248,12 +249,13 @@
             configuration.setName( UUID.randomUUID().toString() );
             configuration.setValueSerializer( valueSerializer );
             configuration.setParentBTree( parentBtree );
-            configuration.setSubBtree( true );
+            configuration.setBtreeType( BTreeTypeEnum.PERSISTED_SUB );
 
             valueBtree = BTreeFactory.createPersistedBTree( configuration );
 
             try
             {
+                // The sub-btree will not be added into the BOB.
                 parentBtree.getRecordManager().manage( valueBtree, RecordManager.INTERNAL_BTREE );
                 raw = null;
             }
@@ -419,6 +421,12 @@
                 e.printStackTrace();
                 return null;
             }
+            catch ( KeyNotFoundException knfe )
+            {
+                // TODO Auto-generated catch block
+                knfe.printStackTrace();
+                return null;
+            }
         }
         else
         {
@@ -655,7 +663,7 @@
         long offset = LongSerializer.deserialize( raw );
 
         // and reload the sub btree
-        valueBtree = parentBtree.getRecordManager().loadDupsBTree( offset );
+        valueBtree = parentBtree.getRecordManager().loadDupsBtree( offset, parentBtree );
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/ReadTransaction.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/ReadTransaction.java
index 3646d13..5128e28 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/ReadTransaction.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/ReadTransaction.java
@@ -21,6 +21,7 @@
 
 
 import java.util.Date;
+import java.util.concurrent.ConcurrentLinkedQueue;
 
 
 /**
@@ -35,7 +36,7 @@
  * A Transaction can be hold for quite a long time, for instance while doing
  * a browse against a big BTree. At some point, transactions which are pending
  * for too long will be closed by the transaction manager.
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  *
  * @param <K> The type for the Key
@@ -49,26 +50,54 @@
     /** The date of creation */
     private long creationDate;
 
-    /** The revision on which we are having a transaction */
-    private volatile Page<K, V> root;
+    /** The associated B-tree header */
+    private BTreeHeader<K, V> btreeHeader;
 
     /** A flag used to tell if a transaction is closed or not */
     private volatile boolean closed;
+    
+    /** The list of read transactions being executed */
+    private ConcurrentLinkedQueue<ReadTransaction<K, V>> readTransactions;
 
-
+    /** The reference to the recordManager, if any */
+    private RecordManager recordManager;
+    
     /**
      * Creates a new transaction instance
-     * 
-     * @param root The associated root
-     * @param revision The revision this transaction is using
-     * @param creationDate The creation date for this transaction
+     *
+     * @param btreeHeader The BtreeHeader we will use for this read transaction
      */
-    public ReadTransaction( Page<K, V> root, long revision, long creationDate )
+    public ReadTransaction( RecordManager recordManager, BTreeHeader<K, V> btreeHeader, ConcurrentLinkedQueue<ReadTransaction<K, V>> readTransactions )
     {
-        this.revision = revision;
-        this.creationDate = creationDate;
-        this.root = root;
-        closed = false;
+        if ( btreeHeader != null )
+        {
+            this.revision = btreeHeader.getRevision();
+            this.creationDate = System.currentTimeMillis();
+            this.btreeHeader = btreeHeader;
+            this.recordManager = recordManager;
+            closed = false;
+        }
+        
+        this.readTransactions = readTransactions;
+    }
+    
+    
+    /**
+     * Creates a new transaction instance
+     *
+     * @param btreeHeader The BtreeHeader we will use for this read transaction
+     */
+    public ReadTransaction( BTreeHeader<K, V> btreeHeader, ConcurrentLinkedQueue<ReadTransaction<K, V>> readTransactions )
+    {
+        if ( btreeHeader != null )
+        {
+            this.revision = btreeHeader.getRevision();
+            this.creationDate = System.currentTimeMillis();
+            this.btreeHeader = btreeHeader;
+            closed = false;
+        }
+        
+        this.readTransactions = readTransactions;
     }
 
 
@@ -82,15 +111,6 @@
 
 
     /**
-     * @return the associated root
-     */
-    public Page<K, V> getRoot()
-    {
-        return root;
-    }
-
-
-    /**
      * @return the creationDate
      */
     public long getCreationDate()
@@ -100,12 +120,31 @@
 
 
     /**
+     * @return the btreeHeader
+     */
+    public BTreeHeader<K, V> getBtreeHeader()
+    {
+        return btreeHeader;
+    }
+
+
+    /**
      * Close the transaction, releasing the revision it was using.
      */
     public void close()
     {
-        root = null;
         closed = true;
+        
+        // Remove the transaction from the list of opened transactions
+        readTransactions.remove( this );
+        
+        // and push the 
+        if ( recordManager != null )
+        {
+            recordManager.releaseTransaction( this );
+        }
+        
+        // Now, get back the copied pages
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java
index a3004ad..3f6ef0e 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java
@@ -26,18 +26,25 @@
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Queue;
 import java.util.Set;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
 import org.apache.directory.mavibot.btree.exception.BTreeCreationException;
 import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
-import org.apache.directory.mavibot.btree.exception.FreePageException;
-import org.apache.directory.mavibot.btree.exception.InvalidBTreeException;
+import org.apache.directory.mavibot.btree.exception.FileException;
+import org.apache.directory.mavibot.btree.exception.InvalidOffsetException;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.exception.RecordManagerException;
 import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
@@ -50,33 +57,36 @@
 
 
 /**
- * The RecordManager is used to manage the file in which we will store the BTrees.
- * A RecordManager will manage more than one BTree.<br/>
+ * The RecordManager is used to manage the file in which we will store the B-trees.
+ * A RecordManager will manage more than one B-tree.<br/>
  *
  * It stores data in fixed size pages (default size is 512 bytes), which may be linked one to
  * the other if the data we want to store is too big for a page.
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-public class RecordManager
+public class RecordManager extends AbstractTransactionManager
 {
     /** The LoggerFactory used by this class */
     protected static final Logger LOG = LoggerFactory.getLogger( RecordManager.class );
 
+    /** The LoggerFactory used by this class */
+    protected static final Logger LOG_PAGES = LoggerFactory.getLogger( "LOG_PAGES" );
+
     /** A dedicated logger for the check */
-    protected static final Logger LOG_CHECK = LoggerFactory.getLogger( "RM_CHECK" );
+    protected static final Logger LOG_CHECK = LoggerFactory.getLogger( "LOG_CHECK" );
 
     /** The associated file */
     private File file;
 
     /** The channel used to read and write data */
-    private FileChannel fileChannel;
+    /* no qualifier */ FileChannel fileChannel;
 
-    /** The number of stored BTrees */
-    private int nbBtree;
+    /** The number of managed B-trees */
+    /* no qualifier */ int nbBtree;
 
     /** The first and last free page */
-    private long firstFreePage;
+    /* no qualifier */ long firstFreePage;
 
     /** The list of available free pages */
     List<PageIO> freePages = new ArrayList<PageIO>();
@@ -86,25 +96,22 @@
     public AtomicLong nbCreatedPages = new AtomicLong( 0 );
     public AtomicLong nbReusedPages = new AtomicLong( 0 );
     public AtomicLong nbUpdateRMHeader = new AtomicLong( 0 );
-    public AtomicLong nbUpdateBTreeHeader = new AtomicLong( 0 );
+    public AtomicLong nbUpdateBtreeHeader = new AtomicLong( 0 );
     public AtomicLong nbUpdatePageIOs = new AtomicLong( 0 );
 
     /** The offset of the end of the file */
     private long endOfFileOffset;
 
     /**
-     * A Btree used to manage the page that has been copied in a new version.
+     * A B-tree used to manage the page that has been copied in a new version.
      * Those pages can be reclaimed when the associated version is dead.
      **/
-    private BTree<RevisionName, long[]> copiedPageBTree;
-
-    /** A BTree used to store all the valid revisions for all the stored BTrees */
-    private BTree<RevisionName, Long> revisionBTree;
+    private BTree<RevisionName, long[]> copiedPageBtree;
 
     /** A constant for an offset on a non existing page */
-    private static final long NO_PAGE = -1L;
+    public static final long NO_PAGE = -1L;
 
-    /** The header page size */
+    /** The number of element we can store in a page */
     private static final int PAGE_SIZE = 4;
 
     /** The size of the link to next page */
@@ -112,44 +119,40 @@
 
     /** Some constants */
     private static final int BYTE_SIZE = 1;
-    private static final int INT_SIZE = 4;
-    private static final int LONG_SIZE = 8;
+    /* no qualifier */ static final int INT_SIZE = 4;
+    /* no qualifier */ static final int LONG_SIZE = 8;
 
     /** The default page size */
-    private static final int DEFAULT_PAGE_SIZE = 512;
+    public static final int DEFAULT_PAGE_SIZE = 512;
 
-    /** The header size */
-    private static int HEADER_SIZE = DEFAULT_PAGE_SIZE;
+    /** The minimal page size. Can't be below 64, as we have to store many thing sin the RMHeader */
+    private static final int MIN_PAGE_SIZE = 64;
 
-    /** A global buffer used to store the header */
-    private static ByteBuffer HEADER_BUFFER;
+    /** The RecordManager header size */
+    /* no qualifier */ static int RECORD_MANAGER_HEADER_SIZE = DEFAULT_PAGE_SIZE;
 
-    /** A static buffer used to store the header */
-    private static byte[] HEADER_BYTES;
+    /** A global buffer used to store the RecordManager header */
+    private static ByteBuffer RECORD_MANAGER_HEADER_BUFFER;
+
+    /** A static buffer used to store the RecordManager header */
+    private static byte[] RECORD_MANAGER_HEADER_BYTES;
 
     /** The length of an Offset, as a negative value */
     private static byte[] LONG_LENGTH = new byte[]
         { ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xF8 };
 
     /** The RecordManager underlying page size. */
-    private int pageSize = DEFAULT_PAGE_SIZE;
+    /* no qualifier */ int pageSize = DEFAULT_PAGE_SIZE;
 
-    /** The set of managed BTrees */
-    private Map<String, BTree<Object, Object>> managedBTrees;
-
-    /** The offset on the last added BTree */
-    private long lastAddedBTreeOffset = NO_PAGE;
+    /** The set of managed B-trees */
+    private Map<String, BTree<Object, Object>> managedBtrees;
+    
+    /** The queue of recently closed transactions */
+    private Queue<RevisionName> closedTransactionsQueue = new LinkedBlockingQueue<RevisionName>();
 
     /** The default file name */
     private static final String DEFAULT_FILE_NAME = "mavibot.db";
 
-    /** A deserializer for Offsets */
-    private static final LongSerializer OFFSET_SERIALIZER = new LongSerializer();
-
-    private static final String REVISION_BTREE_NAME = "_revisionBTree_";
-
-    private static final String COPIED_PAGE_BTREE_NAME = "_copiedPageBTree_";
-
     /** A flag set to true if we want to keep old revisions */
     private boolean keepRevisions;
 
@@ -159,18 +162,48 @@
     /** A flag used by internal btrees */
     public static final boolean NORMAL_BTREE = false;
 
-    /** A map of pending pages */
-    private Map<Page<?, ?>, BTree<?, ?>> pendingPages = new LinkedHashMap<Page<?, ?>, BTree<?, ?>>();
-
-    /** The Btree of Btrees */
+    /** The B-tree of B-trees */
     private BTree<NameRevision, Long> btreeOfBtrees;
 
-    private static final String BOB_ONE_NAME = "_BTREE_OF_BTREES_";
+    /** The B-tree of B-trees management btree name */
+    /* no qualifier */ static final String BTREE_OF_BTREES_NAME = "_btree_of_btrees_";
 
-    /** The two latest revisions of the BOB */
-    private long bobCurrentRevision;
-    private long bobOldRevision;
+    /** The CopiedPages management btree name */
+    /* no qualifier */ static final String COPIED_PAGE_BTREE_NAME = "_copiedPageBtree_";
 
+    /** The current B-tree of B-trees header offset */
+    /* no qualifier */ long currentBtreeOfBtreesOffset;
+
+    /** The previous B-tree of B-trees header offset */
+    private long previousBtreeOfBtreesOffset = NO_PAGE;
+
+    /** The offset on the current copied pages B-tree */
+    /* no qualifier */ long currentCopiedPagesBtreeOffset = NO_PAGE;
+
+    /** The offset on the previous copied pages B-tree */
+    private long previousCopiedPagesBtreeOffset = NO_PAGE;
+
+    /** A lock to protect the transaction handling */
+    private Lock transactionLock = new ReentrantLock();
+    
+    /** A ThreadLocalStorage used to store the current transaction */
+    private static final ThreadLocal<Integer> context = new ThreadLocal<Integer>();
+
+    /** The list of PageIO that can be freed after a commit */
+    List<PageIO> freedPages = new ArrayList<PageIO>();
+
+    /** The list of PageIO that can be freed after a roolback */
+    private List<PageIO> allocatedPages = new ArrayList<PageIO>();
+    
+    /** A Map keeping the latest revisions for each managed BTree */
+    private Map<String, BTreeHeader<?, ?>> currentBTreeHeaders = new HashMap<String, BTreeHeader<?, ?>>();
+
+    /** A Map storing the new revisions when some change have been made in some BTrees */
+    private Map<String, BTreeHeader<?, ?>> newBTreeHeaders = new HashMap<String, BTreeHeader<?, ?>>();
+    
+    /** A lock to protect the BtreeHeader maps */
+    private ReadWriteLock btreeHeadersLock = new ReentrantReadWriteLock();
+    
     /**
      * Create a Record manager which will either create the underlying file
      * or load an existing one. If a folder is provided, then we will create
@@ -190,15 +223,24 @@
      * a file with a default name : mavibot.db
      *
      * @param name The file name, or a folder name
-     * @param pageSize the size of a page on disk
+     * @param pageSize the size of a page on disk, in bytes
      */
     public RecordManager( String fileName, int pageSize )
     {
-        managedBTrees = new LinkedHashMap<String, BTree<Object, Object>>();
+        managedBtrees = new LinkedHashMap<String, BTree<Object, Object>>();
 
-        HEADER_BUFFER = ByteBuffer.allocate( pageSize );
-        HEADER_BYTES = new byte[pageSize];
-        HEADER_SIZE = pageSize;
+        if ( pageSize < MIN_PAGE_SIZE )
+        {
+            this.pageSize = MIN_PAGE_SIZE;
+        }
+        else
+        {
+            this.pageSize = pageSize;
+        }
+
+        RECORD_MANAGER_HEADER_BUFFER = ByteBuffer.allocate( this.pageSize );
+        RECORD_MANAGER_HEADER_BYTES = new byte[this.pageSize];
+        RECORD_MANAGER_HEADER_SIZE = this.pageSize;
 
         // Open the file or create it
         File tmpFile = new File( fileName );
@@ -222,7 +264,6 @@
 
             if ( isNewFile )
             {
-                this.pageSize = pageSize;
                 initRecordManager();
             }
             else
@@ -264,33 +305,35 @@
             LOG.error( "Cannot create the file {}", mavibotFile.getName() );
             return false;
         }
-
     }
 
+
     /**
-     * We will create a brand new RecordManager file, containing nothing, but the header,
-     * a BTree to manage the old revisions we want to keep and
-     * a BTree used to manage pages associated with old versions.
+     * We will create a brand new RecordManager file, containing nothing, but the RecordManager header,
+     * a B-tree to manage the old revisions we want to keep and
+     * a B-tree used to manage pages associated with old versions.
      * <br/>
-     * The Header contains the following details :
+     * The RecordManager header contains the following details :
      * <pre>
-     * +---------------+
-     * | PageSize      | 4 bytes : The size of a physical page (default to 4096)
-     * +---------------+
-     * |  NbTree       | 4 bytes : The number of managed BTrees (at least 1)
-     * +---------------+
-     * | FirstFree     | 8 bytes : The offset of the first free page
-     * +---------------+
-     * | currentBoB    | 1 byte : The current BoB in use
-     * +---------------+
-     * | BoB offset[0] | 8 bytes : The offset of the first BoB
-     * +---------------+
-     * | BoB offset[1] | 8 bytes : The offset of the second BoB
-     * +---------------+
+     * +--------------------------+
+     * | PageSize                 | 4 bytes : The size of a physical page (default to 4096)
+     * +--------------------------+
+     * |  NbTree                  | 4 bytes : The number of managed B-trees (at least 1)
+     * +--------------------------+
+     * | FirstFree                | 8 bytes : The offset of the first free page
+     * +--------------------------+
+     * | current BoB offset       | 8 bytes : The offset of the current BoB
+     * +--------------------------+
+     * | previous BoB offset      | 8 bytes : The offset of the previous BoB
+     * +--------------------------+
+     * | current CP btree offset  | 8 bytes : The offset of the current BoB
+     * +--------------------------+
+     * | previous CP btree offset | 8 bytes : The offset of the previous BoB
+     * +--------------------------+
      * </pre>
      *
-     * We then store the BTree managing the pages that have been copied when we have added
-     * or deleted an element in the BTree. They are associated with a version.
+     * We then store the B-tree managing the pages that have been copied when we have added
+     * or deleted an element in the B-tree. They are associated with a version.
      *
      * Last, we add the bTree that keep a track on each revision we can have access to.
      */
@@ -299,8 +342,7 @@
         // Create a new Header
         nbBtree = 0;
         firstFreePage = NO_PAGE;
-        bobCurrentRevision = 0L;
-        bobOldRevision = 0L;
+        currentBtreeOfBtreesOffset = 0L;
 
         updateRecordManagerHeader();
 
@@ -308,22 +350,32 @@
         endOfFileOffset = fileChannel.size();
 
         // First, create the btree of btrees <NameRevision, Long>
-        btreeOfBtrees = BTreeFactory.createPersistedBTree( BOB_ONE_NAME, new NameRevisionSerializer(),
-            new LongSerializer() );
+        createBtreeOfBtrees();
 
-        // Now, initialize the Copied Page BTree
-        copiedPageBTree = BTreeFactory.createPersistedBTree( COPIED_PAGE_BTREE_NAME, new RevisionNameSerializer(),
-            new LongArraySerializer() );
+        // Now, initialize the Copied Page B-tree
+        createCopiedPagesBtree();
 
-        // and initialize the Revision BTree
-        revisionBTree = BTreeFactory.createPersistedBTree( REVISION_BTREE_NAME, new RevisionNameSerializer(),
-            new LongSerializer() );
-
-        // Inject these BTrees into the RecordManager
+        // Inject these B-trees into the RecordManager. They are internal B-trees.
         try
         {
-            manage( copiedPageBTree );
-            manage( revisionBTree );
+            manage( btreeOfBtrees, INTERNAL_BTREE );
+
+            currentBtreeOfBtreesOffset = ((PersistedBTree<NameRevision, Long>)btreeOfBtrees).getBtreeHeader().getBTreeHeaderOffset();
+            updateRecordManagerHeader();
+            
+            // Inject the BtreeOfBtrees into the currentBtreeHeaders map
+            currentBTreeHeaders.put( BTREE_OF_BTREES_NAME,  ((PersistedBTree<NameRevision, Long>)btreeOfBtrees).getBtreeHeader() );
+            newBTreeHeaders.put( BTREE_OF_BTREES_NAME,  ((PersistedBTree<NameRevision, Long>)btreeOfBtrees).getBtreeHeader() );
+
+            // The FreePage B-tree
+            manage( copiedPageBtree, INTERNAL_BTREE );
+
+            currentCopiedPagesBtreeOffset = ((PersistedBTree<RevisionName, long[]>)copiedPageBtree).getBtreeHeader().getBTreeHeaderOffset();
+            updateRecordManagerHeader();
+            
+            // Inject the CopiedPagesBTree into the currentBtreeHeaders map
+            currentBTreeHeaders.put( COPIED_PAGE_BTREE_NAME, ((PersistedBTree<RevisionName, long[]>)copiedPageBtree).getBtreeHeader() );
+            newBTreeHeaders.put( COPIED_PAGE_BTREE_NAME, ((PersistedBTree<RevisionName, long[]>)copiedPageBtree).getBtreeHeader() );
         }
         catch ( BTreeAlreadyManagedException btame )
         {
@@ -335,109 +387,164 @@
 
 
     /**
+     * Create the B-treeOfBtrees
+     */
+    private void createBtreeOfBtrees()
+    {
+        PersistedBTreeConfiguration<NameRevision, Long> configuration = new PersistedBTreeConfiguration<NameRevision, Long>();
+        configuration.setKeySerializer( NameRevisionSerializer.INSTANCE );
+        configuration.setName( BTREE_OF_BTREES_NAME );
+        configuration.setValueSerializer( LongSerializer.INSTANCE );
+        configuration.setBtreeType( BTreeTypeEnum.BTREE_OF_BTREES );
+        configuration.setCacheSize( PersistedBTree.DEFAULT_CACHE_SIZE );
+
+        btreeOfBtrees = BTreeFactory.createPersistedBTree( configuration );
+    }
+
+
+    /**
+     * Create the CopiedPagesBtree
+     */
+    private void createCopiedPagesBtree()
+    {
+        PersistedBTreeConfiguration<RevisionName, long[]> configuration = new PersistedBTreeConfiguration<RevisionName, long[]>();
+        configuration.setKeySerializer( RevisionNameSerializer.INSTANCE );
+        configuration.setName( COPIED_PAGE_BTREE_NAME );
+        configuration.setValueSerializer( LongArraySerializer.INSTANCE );
+        configuration.setBtreeType( BTreeTypeEnum.COPIED_PAGES_BTREE );
+        configuration.setCacheSize( PersistedBTree.DEFAULT_CACHE_SIZE );
+
+        copiedPageBtree = BTreeFactory.createPersistedBTree( configuration );
+    }
+
+
+    /**
      * Load the BTrees from the disk.
      *
      * @throws InstantiationException
      * @throws IllegalAccessException
      * @throws ClassNotFoundException
+     * @throws NoSuchFieldException
+     * @throws SecurityException
+     * @throws IllegalArgumentException
      */
     private void loadRecordManager() throws IOException, ClassNotFoundException, IllegalAccessException,
-        InstantiationException
+        InstantiationException, IllegalArgumentException, SecurityException, NoSuchFieldException, KeyNotFoundException
     {
         if ( fileChannel.size() != 0 )
         {
-            ByteBuffer header = ByteBuffer.allocate( HEADER_SIZE );
+            ByteBuffer recordManagerHeader = ByteBuffer.allocate( RECORD_MANAGER_HEADER_SIZE );
 
             // The file exists, we have to load the data now
-            fileChannel.read( header );
+            fileChannel.read( recordManagerHeader );
 
-            header.rewind();
+            recordManagerHeader.rewind();
 
             // read the RecordManager Header :
-            // +----------------+
-            // | PageSize       | 4 bytes : The size of a physical page (default to 4096)
-            // +----------------+
-            // | NbTree         | 4 bytes : The number of managed BTrees (at least 1)
-            // +----------------+
-            // | FirstFree      | 8 bytes : The offset of the first free page
-            // +----------------+
-            // | BoB old offset | 8 bytes : The previous BoB revision
-            // +----------------+
-            // | BoB new offset | 8 bytes : The current BoB revision
-            // +----------------+
+            // +---------------------+
+            // | PageSize            | 4 bytes : The size of a physical page (default to 4096)
+            // +---------------------+
+            // | NbTree              | 4 bytes : The number of managed B-trees (at least 1)
+            // +---------------------+
+            // | FirstFree           | 8 bytes : The offset of the first free page
+            // +---------------------+
+            // | current BoB offset  | 8 bytes : The offset of the current B-tree of B-trees
+            // +---------------------+
+            // | previous BoB offset | 8 bytes : The offset of the previous B-tree of B-trees
+            // +---------------------+
+            // | current CP offset   | 8 bytes : The offset of the current Copied Pages B-tree
+            // +---------------------+
+            // | previous CP offset  | 8 bytes : The offset of the previous Copied Pages B-tree
+            // +---------------------+
 
             // The page size
-            pageSize = header.getInt();
+            pageSize = recordManagerHeader.getInt();
 
-            // The number of managed BTrees
-            nbBtree = header.getInt();
+            // The number of managed B-trees
+            nbBtree = recordManagerHeader.getInt();
 
             // The first and last free page
-            firstFreePage = header.getLong();
+            firstFreePage = recordManagerHeader.getLong();
 
-            // The BOB revisions
-            long bobRevision1 = header.getLong();
-            long bobRevision2 = header.getLong();
+            // The current BOB offset
+            currentBtreeOfBtreesOffset = recordManagerHeader.getLong();
 
-            if ( bobRevision1 < bobRevision2 )
+            // The previous BOB offset
+            previousBtreeOfBtreesOffset = recordManagerHeader.getLong();
+
+            // The current Copied Pages B-tree offset
+            currentCopiedPagesBtreeOffset = recordManagerHeader.getLong();
+
+            // The previous Copied Pages B-tree offset
+            previousCopiedPagesBtreeOffset = recordManagerHeader.getLong();
+
+            // read the B-tree of B-trees
+            PageIO[] bobHeaderPageIos = readPageIOs( currentBtreeOfBtreesOffset, Long.MAX_VALUE );
+
+            btreeOfBtrees = BTreeFactory.<NameRevision, Long> createPersistedBTree( BTreeTypeEnum.BTREE_OF_BTREES );
+            //BTreeFactory.<NameRevision, Long> setBtreeHeaderOffset( ( PersistedBTree<NameRevision, Long> )btreeOfBtrees, currentBtreeOfBtreesOffset );
+
+            loadBtree( bobHeaderPageIos, btreeOfBtrees );
+
+            // read the copied page B-tree
+            PageIO[] copiedPagesPageIos = readPageIOs( currentCopiedPagesBtreeOffset, Long.MAX_VALUE );
+
+            copiedPageBtree = BTreeFactory.<RevisionName, long[]> createPersistedBTree( BTreeTypeEnum.COPIED_PAGES_BTREE );
+            //( ( PersistedBTree<RevisionName, long[]> ) copiedPageBtree ).setBtreeHeaderOffset( currentCopiedPagesBtreeOffset );
+
+            loadBtree( copiedPagesPageIos, copiedPageBtree );
+
+            // Now, read all the B-trees from the btree of btrees
+            TupleCursor<NameRevision, Long> btreeCursor = btreeOfBtrees.browse();
+            Map<String, Long> loadedBtrees = new HashMap<String, Long>();
+
+            // loop on all the btrees we have, and keep only the latest revision
+            long currentRevision = -1L;
+
+            while ( btreeCursor.hasNext() )
             {
-                bobOldRevision = bobRevision1;
-                bobCurrentRevision = bobRevision2;
-            }
-            else if ( bobRevision1 > bobRevision2 )
-            {
-                bobOldRevision = bobRevision2;
-                bobCurrentRevision = bobRevision1;
-            }
-            else
-            {
-                // Special case : the RecordManage has been shtudown correctly
-                bobOldRevision = bobRevision1;
-                bobCurrentRevision = bobRevision2;
+                Tuple<NameRevision, Long> btreeTuple = btreeCursor.next();
+                NameRevision nameRevision = btreeTuple.getKey();
+                long btreeOffset = btreeTuple.getValue();
+                long revision = nameRevision.getValue();
+
+                // Check if we already have processed this B-tree
+                Long loadedBtreeRevision = loadedBtrees.get( nameRevision.getName() );
+
+                if ( loadedBtreeRevision != null )
+                {
+                    // The btree has already been loaded. The revision is necessarily higher
+                    if ( revision > currentRevision )
+                    {
+                        // We have a newer revision : switch to the new revision (we keep the offset atm)
+                        loadedBtrees.put( nameRevision.getName(), btreeOffset );
+                        currentRevision = revision;
+                    }
+                }
+                else
+                {
+                    // This is a new B-tree
+                    loadedBtrees.put( nameRevision.getName(), btreeOffset );
+                    currentRevision = nameRevision.getRevision();
+                }
             }
 
-            // Now read each BTree. The first one is the one which
-            // manage the modified pages. Once read, we can discard all
-            // the pages that are stored in it, as we have restarted
-            // the RecordManager.
-            long btreeOffset = HEADER_SIZE;
+            // TODO : clean up the old revisions...
 
-            PageIO[] pageIos = readPageIOs( HEADER_SIZE, Long.MAX_VALUE );
 
-            // Create the BTree
-            copiedPageBTree = BTreeFactory.<RevisionName, long[]> createPersistedBTree();
-            ( ( PersistedBTree<RevisionName, long[]> ) copiedPageBTree ).setBtreeOffset( btreeOffset );
-
-            loadBTree( pageIos, copiedPageBTree );
-            long nextBtreeOffset = ( ( PersistedBTree<RevisionName, long[]> ) copiedPageBTree ).getNextBTreeOffset();
-
-            // And the Revision BTree
-            pageIos = readPageIOs( nextBtreeOffset, Long.MAX_VALUE );
-
-            revisionBTree = BTreeFactory.<RevisionName, Long> createPersistedBTree();
-            ( ( PersistedBTree<RevisionName, Long> ) revisionBTree ).setBtreeOffset( nextBtreeOffset );
-
-            loadBTree( pageIos, revisionBTree );
-            nextBtreeOffset = ( ( PersistedBTree<RevisionName, Long> ) revisionBTree ).getNextBTreeOffset();
-
-            // Then process the next ones
-            for ( int i = 2; i < nbBtree; i++ )
+            // Now, we can load the real btrees using the offsets
+            for ( String btreeName : loadedBtrees.keySet() )
             {
-                // Create the BTree
-                BTree<Object, Object> btree = BTreeFactory.createPersistedBTree();
-                ( ( PersistedBTree<Object, Object> ) btree ).setRecordManager( this );
-                ( ( PersistedBTree<Object, Object> ) btree ).setBtreeOffset( nextBtreeOffset );
-                lastAddedBTreeOffset = nextBtreeOffset;
+                long btreeOffset = loadedBtrees.get( btreeName );
 
-                // Read the associated pages
-                pageIos = readPageIOs( nextBtreeOffset, Long.MAX_VALUE );
+                PageIO[] btreePageIos = readPageIOs( btreeOffset, Long.MAX_VALUE );
 
-                // Load the BTree
-                loadBTree( pageIos, btree );
-                nextBtreeOffset = ( ( PersistedBTree<Object, Object> ) btree ).getNextBTreeOffset();
+                BTree<?, ?> btree = BTreeFactory.<NameRevision, Long> createPersistedBTree();
+                //( ( PersistedBTree<NameRevision, Long> ) btree ).setBtreeHeaderOffset( btreeOffset );
+                loadBtree( btreePageIos, btree );
 
-                // Store it into the managedBtrees map
-                managedBTrees.put( btree.getName(), btree );
+                // Add the btree into the map of managed B-trees
+                managedBtrees.put( btreeName, ( BTree<Object, Object> ) btree );
             }
 
             // We are done ! Let's finish with the last initialization parts
@@ -447,13 +554,170 @@
 
 
     /**
+     * Starts a transaction
+     */
+    public void beginTransaction()
+    {
+        // First, take the lock
+        transactionLock.lock();
+        
+        // Now, check the TLS state
+        Integer nbTxnLevel = context.get();
+        
+        if ( nbTxnLevel == null )
+        {
+            context.set( 1 );
+        }
+        else
+        {
+            // And increment the counter of inner txn.
+            context.set( nbTxnLevel + 1 );
+        }
+    }
+
+
+    /**
+     * Commits a transaction
+     */
+    public void commit()
+    {
+        if ( !fileChannel.isOpen() )
+        {
+            // The file has been closed, nothing remains to commit, let's get out
+            transactionLock.unlock();
+            return;
+        }
+
+        int nbTxnStarted = context.get();
+        
+        switch ( nbTxnStarted )
+        {
+            case 0 :
+                // The transaction was rollbacked, quit immediatelly
+                transactionLock.unlock();
+                
+                return;
+            
+            case 1 :
+                // We are done with the transaction, we can update the RMHeader and swap the BTreeHeaders
+                // First update the RMHeader to be sure that we have a way to restore from a crash
+                updateRecordManagerHeader();
+                
+                // Swap the BtreeHeaders maps
+                swapCurrentBtreeHeaders();
+        
+                // We can now free pages
+                for ( PageIO pageIo : freedPages )
+                {
+                    try
+                    {
+                        free( pageIo );
+                    }
+                    catch ( IOException ioe )
+                    {
+                        throw new RecordManagerException( ioe.getMessage() );
+                    }
+                }
+        
+                // Release the allocated and freed pages list
+                freedPages.clear();
+                allocatedPages.clear();
+        
+                // And update the RMHeader again, removing the old references to BOB and CPB b-tree headers
+                // here, we have to erase the old references to keep only the new ones.
+                updateRecordManagerHeader();
+                
+                // And decrement the number of started transactions
+                context.set( nbTxnStarted - 1 );
+
+                // Finally, release the global lock
+                transactionLock.unlock();
+                
+                return;
+                
+            default :
+                // We are inner an existing transaction. Just update the necessary elements
+                // Update the RMHeader to be sure that we have a way to restore from a crash
+                updateRecordManagerHeader();
+                
+                // Swap the BtreeHeaders maps
+                swapCurrentBtreeHeaders();
+        
+                // We can now free pages
+                for ( PageIO pageIo : freedPages )
+                {
+                    try
+                    {
+                        free( pageIo );
+                    }
+                    catch ( IOException ioe )
+                    {
+                        throw new RecordManagerException( ioe.getMessage() );
+                    }
+                }
+        
+                // Release the allocated and freed pages list
+                freedPages.clear();
+                allocatedPages.clear();
+        
+                // And update the RMHeader again, removing the old references to BOB and CPB b-tree headers
+                // here, we have to erase the old references to keep only the new ones.
+                updateRecordManagerHeader();
+                
+                // And decrement the number of started transactions
+                context.set( nbTxnStarted - 1 );
+
+                // Finally, release the global lock
+                transactionLock.unlock();
+                return;
+        }
+    }
+
+
+    /**
+     * Rollback a transaction
+     */
+    public void rollback()
+    {
+        // Reset the counter
+        context.set( 0 );
+
+        // We can now free allocated pages, this is the end of the transaction
+        for ( PageIO pageIo : allocatedPages )
+        {
+            try
+            {
+                free( pageIo );
+            }
+            catch ( IOException ioe )
+            {
+                throw new RecordManagerException( ioe.getMessage() );
+            }
+        }
+
+        // Release the allocated and freed pages list
+        freedPages.clear();
+        allocatedPages.clear();
+
+        // And update the RMHeader
+        updateRecordManagerHeader();
+        
+        // And restore the BTreeHeaders new Map to the current state
+        revertBtreeHeaders();
+
+        transactionLock.unlock();
+    }
+
+
+    /**
      * Reads all the PageIOs that are linked to the page at the given position, including
      * the first page.
      *
      * @param position The position of the first page
+     * @param limit The maximum bytes to read. Set this value to -1 when the size is unknown.
      * @return An array of pages
      */
-    private PageIO[] readPageIOs( long position, long limit ) throws IOException, EndOfFileExceededException
+    /*no qualifier*/ PageIO[] readPageIOs( long position, long limit ) throws IOException, EndOfFileExceededException
     {
         LOG.debug( "Read PageIOs at position {}", position );
 
@@ -497,52 +761,105 @@
 
 
     /**
-     * Read a BTree from the disk. The meta-data are at the given position in the list of pages.
+     * Check the offset to be sure it's a valid one :
+     * <ul>
+     * <li>It's >= 0</li>
+     * <li>It's below the end of the file</li>
+     * <li>It's a multipl of the pageSize
+     * </ul>
+     * @param offset The offset to check
+     * @throws InvalidOffsetException If the offset is not valid
+     */
+    private void checkOffset( long offset )
+    {
+        if ( ( offset < 0 ) || ( offset > endOfFileOffset ) || ( ( offset % pageSize ) != 0 ) )
+        {
+            throw new InvalidOffsetException( "Bad Offset : " + offset );
+        }
+    }
+
+
+    /**
+     * Read a B-tree from the disk. The meta-data are at the given position in the list of pages.
+     * We load a B-tree in two steps : first, we load the B-tree header, then the common informations
      *
      * @param pageIos The list of pages containing the meta-data
-     * @param btree The BTree we have to initialize
+     * @param btree The B-tree we have to initialize
      * @throws InstantiationException
      * @throws IllegalAccessException
      * @throws ClassNotFoundException
+     * @throws NoSuchFieldException
+     * @throws SecurityException
+     * @throws IllegalArgumentException
      */
-    private <K, V> void loadBTree( PageIO[] pageIos, BTree<K, V> btree ) throws EndOfFileExceededException,
-        IOException, ClassNotFoundException, IllegalAccessException, InstantiationException
+    private <K, V> void loadBtree( PageIO[] pageIos, BTree<K, V> btree ) throws EndOfFileExceededException,
+        IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, IllegalArgumentException, SecurityException, NoSuchFieldException
+    {
+        loadBtree( pageIos, btree, null );
+    }
+
+
+    /**
+     * Read a B-tree from the disk. The meta-data are at the given position in the list of pages.
+     * We load a B-tree in two steps : first, we load the B-tree header, then the common informations
+     *
+     * @param pageIos The list of pages containing the meta-data
+     * @param btree The B-tree we have to initialize
+     * @throws InstantiationException
+     * @throws IllegalAccessException
+     * @throws ClassNotFoundException
+     * @throws NoSuchFieldException
+     * @throws SecurityException
+     * @throws IllegalArgumentException
+     */
+    /* no qualifier */ <K, V> void loadBtree( PageIO[] pageIos, BTree btree, BTree<K, V> parentBTree ) throws EndOfFileExceededException,
+        IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, IllegalArgumentException, SecurityException, NoSuchFieldException
     {
         long dataPos = 0L;
 
-        // The BTree current revision
+        // Process the B-tree header
+        BTreeHeader<K, V> btreeHeader = new BTreeHeader<K, V>();
+        btreeHeader.setBtree( btree );
+
+        // The BtreeHeader offset
+        btreeHeader.setBTreeHeaderOffset( pageIos[0].getOffset() );
+
+        // The B-tree current revision
         long revision = readLong( pageIos, dataPos );
-        BTreeFactory.setRevision( btree, revision );
+        btreeHeader.setRevision( revision );
         dataPos += LONG_SIZE;
 
         // The nb elems in the tree
         long nbElems = readLong( pageIos, dataPos );
-        BTreeFactory.setNbElems( btree, nbElems );
+        btreeHeader.setNbElems( nbElems );
         dataPos += LONG_SIZE;
 
-        // The BTree rootPage offset
+        // The B-tree rootPage offset
         long rootPageOffset = readLong( pageIos, dataPos );
-        BTreeFactory.setRootPageOffset( btree, rootPageOffset );
+        btreeHeader.setRootPageOffset( rootPageOffset );
         dataPos += LONG_SIZE;
 
-        // The next BTree offset
-        long nextBTreeOffset = readLong( pageIos, dataPos );
-        BTreeFactory.setNextBTreeOffset( btree, nextBTreeOffset );
-        dataPos += LONG_SIZE;
+        // The B-tree information offset
+        long btreeInfoOffset = readLong( pageIos, dataPos );
 
-        // The BTree page size
-        int btreePageSize = readInt( pageIos, dataPos );
+        // Now, process the common informations
+        PageIO[] infoPageIos = readPageIOs( btreeInfoOffset, Long.MAX_VALUE );
+        ((PersistedBTree<K, V>)btree).setBtreeInfoOffset( infoPageIos[0].getOffset() );
+        dataPos = 0L;
+
+        // The B-tree page size
+        int btreePageSize = readInt( infoPageIos, dataPos );
         BTreeFactory.setPageSize( btree, btreePageSize );
         dataPos += INT_SIZE;
 
         // The tree name
-        ByteBuffer btreeNameBytes = readBytes( pageIos, dataPos );
+        ByteBuffer btreeNameBytes = readBytes( infoPageIos, dataPos );
         dataPos += INT_SIZE + btreeNameBytes.limit();
         String btreeName = Strings.utf8ToString( btreeNameBytes );
         BTreeFactory.setName( btree, btreeName );
 
         // The keySerializer FQCN
-        ByteBuffer keySerializerBytes = readBytes( pageIos, dataPos );
+        ByteBuffer keySerializerBytes = readBytes( infoPageIos, dataPos );
         dataPos += INT_SIZE + keySerializerBytes.limit();
 
         String keySerializerFqcn = "";
@@ -555,7 +872,7 @@
         BTreeFactory.setKeySerializer( btree, keySerializerFqcn );
 
         // The valueSerialier FQCN
-        ByteBuffer valueSerializerBytes = readBytes( pageIos, dataPos );
+        ByteBuffer valueSerializerBytes = readBytes( infoPageIos, dataPos );
 
         String valueSerializerFqcn = "";
         dataPos += INT_SIZE + valueSerializerBytes.limit();
@@ -567,19 +884,25 @@
 
         BTreeFactory.setValueSerializer( btree, valueSerializerFqcn );
 
-        // The BTree allowDuplicates flag
-        int allowDuplicates = readInt( pageIos, dataPos );
+        // The B-tree allowDuplicates flag
+        int allowDuplicates = readInt( infoPageIos, dataPos );
         ( ( PersistedBTree<K, V> ) btree ).setAllowDuplicates( allowDuplicates != 0 );
         dataPos += INT_SIZE;
 
-        // Now, init the BTree
-        btree.init();
-
+        // Set the recordManager in the btree
         ( ( PersistedBTree<K, V> ) btree ).setRecordManager( this );
 
-        // Now, load the rootPage, which can be a Leaf or a Node, depending
-        // on the number of elements in the tree : if it's above the pageSize,
-        // it's a Node, otherwise it's a Leaf
+        // Set the current revision to the one stored in the B-tree header
+        // Here, we have to tell the BTree to keep this revision in the
+        // btreeRevisions Map, thus the 'true' parameter at the end.
+        ((PersistedBTree<K, V>)btree).storeRevision( btreeHeader, true );
+
+        // Now, init the B-tree
+        ( ( PersistedBTree<K, V> ) btree ).init( parentBTree );
+        
+        // Update the BtreeHeaders Maps
+        currentBTreeHeaders.put( btree.getName(), ( ( PersistedBTree<K, V> ) btree ).getBtreeHeader() );
+        newBTreeHeaders.put( btree.getName(), ( ( PersistedBTree<K, V> ) btree ).getBtreeHeader() );
 
         // Read the rootPage pages on disk
         PageIO[] rootPageIos = readPageIOs( rootPageOffset, Long.MAX_VALUE );
@@ -591,31 +914,33 @@
     }
 
 
-    private <K, V> Page<K, V> readNode( BTree<K, V> btree, long offset, long revision, int nbElems ) throws IOException
-    {
-        Page<K, V> node = BTreeFactory.createNode( btree, revision, nbElems );
-
-        // Read the rootPage pages on disk
-        PageIO[] pageIos = readPageIOs( offset, Long.MAX_VALUE );
-
-        return node;
-    }
-
-
+    /**
+     * Deserialize a Page from a B-tree at a give position
+     *
+     * @param btree The B-tree we want to read a Page from
+     * @param offset The position in the file for this page
+     * @return The read page
+     * @throws EndOfFileExceededException If we have reached the end of the file while reading the page
+     */
     public <K, V> Page<K, V> deserialize( BTree<K, V> btree, long offset ) throws EndOfFileExceededException,
         IOException
     {
+        checkOffset( offset );
         PageIO[] rootPageIos = readPageIOs( offset, Long.MAX_VALUE );
 
         Page<K, V> page = readPage( btree, rootPageIos );
 
-        ( ( AbstractPage<K, V> ) page ).setOffset( rootPageIos[0].getOffset() );
-        ( ( AbstractPage<K, V> ) page ).setLastOffset( rootPageIos[rootPageIos.length - 1].getOffset() );
-
         return page;
     }
 
 
+    /**
+     * Read a page from some PageIO for a given B-tree
+     * @param btree The B-tree we want to read a page for
+     * @param pageIos The PageIO containing the raw data
+     * @return The read Page if successful
+     * @throws IOException If the deserialization failed
+     */
     private <K, V> Page<K, V> readPage( BTree<K, V> btree, PageIO[] pageIos ) throws IOException
     {
         // Deserialize the rootPage now
@@ -651,6 +976,12 @@
             page = readNodeKeysAndValues( btree, -nbElems, revision, byteBuffer, pageIos );
         }
 
+        ( ( AbstractPage<K, V> ) page ).setOffset( pageIos[0].getOffset() );
+        if ( pageIos.length > 1 )
+        {
+            ( ( AbstractPage<K, V> ) page ).setLastOffset( pageIos[pageIos.length - 1].getOffset() );
+        }
+
         return page;
     }
 
@@ -659,8 +990,7 @@
      * Deserialize a Leaf from some PageIOs
      */
     private <K, V> PersistedLeaf<K, V> readLeafKeysAndValues( BTree<K, V> btree, int nbElems, long revision,
-        ByteBuffer byteBuffer,
-        PageIO[] pageIos )
+        ByteBuffer byteBuffer, PageIO[] pageIos )
     {
         // Its a leaf, create it
         PersistedLeaf<K, V> leaf = ( PersistedLeaf<K, V> ) BTreeFactory.createLeaf( btree, revision, nbElems );
@@ -717,8 +1047,7 @@
      * Deserialize a Node from some PageIos
      */
     private <K, V> PersistedNode<K, V> readNodeKeysAndValues( BTree<K, V> btree, int nbElems, long revision,
-        ByteBuffer byteBuffer,
-        PageIO[] pageIos ) throws IOException
+        ByteBuffer byteBuffer, PageIO[] pageIos ) throws IOException
     {
         PersistedNode<K, V> node = ( PersistedNode<K, V> ) BTreeFactory.createNode( btree, revision, nbElems );
 
@@ -726,8 +1055,8 @@
         for ( int i = 0; i < nbElems; i++ )
         {
             // This is an Offset
-            long offset = OFFSET_SERIALIZER.deserialize( byteBuffer );
-            long lastOffset = OFFSET_SERIALIZER.deserialize( byteBuffer );
+            long offset = LongSerializer.INSTANCE.deserialize( byteBuffer );
+            long lastOffset = LongSerializer.INSTANCE.deserialize( byteBuffer );
 
             PersistedPageHolder<K, V> valueHolder = new PersistedPageHolder<K, V>( btree, null, offset, lastOffset );
             node.setValue( i, valueHolder );
@@ -747,8 +1076,8 @@
         }
 
         // and read the last value, as it's a node
-        long offset = OFFSET_SERIALIZER.deserialize( byteBuffer );
-        long lastOffset = OFFSET_SERIALIZER.deserialize( byteBuffer );
+        long offset = LongSerializer.INSTANCE.deserialize( byteBuffer );
+        long lastOffset = LongSerializer.INSTANCE.deserialize( byteBuffer );
 
         PersistedPageHolder<K, V> valueHolder = new PersistedPageHolder<K, V>( btree, null, offset, lastOffset );
         node.setValue( nbElems, valueHolder );
@@ -759,11 +1088,12 @@
 
     /**
      * Read a byte[] from pages.
+     *
      * @param pageIos The pages we want to read the byte[] from
      * @param position The position in the data stored in those pages
      * @return The byte[] we have read
      */
-    private ByteBuffer readBytes( PageIO[] pageIos, long position )
+    /* no qualifier */ ByteBuffer readBytes( PageIO[] pageIos, long position )
     {
         // Read the byte[] length first
         int length = readInt( pageIos, position );
@@ -787,7 +1117,6 @@
         else
         {
             ByteBuffer bytes = ByteBuffer.allocate( length );
-            int bytesPos = 0;
 
             while ( length > 0 )
             {
@@ -814,7 +1143,6 @@
                 pageData.reset();
                 pageNb++;
                 pagePos = LINK_SIZE;
-                bytesPos += remaining;
                 pageData = pageIos[pageNb].getData();
                 length -= remaining;
                 remaining = pageData.capacity() - pagePos;
@@ -833,7 +1161,7 @@
      * @param position The position in the data stored in those pages
      * @return The int we have read
      */
-    private int readInt( PageIO[] pageIos, long position )
+    /* no qualifier */ int readInt( PageIO[] pageIos, long position )
     {
         // Compute the page in which we will store the data given the
         // current position
@@ -923,7 +1251,7 @@
      * @param position The position in the data stored in those pages
      * @return The long we have read
      */
-    private long readLong( PageIO[] pageIos, long position )
+    /* no qualifier */ long readLong( PageIO[] pageIos, long position )
     {
         // Compute the page in which we will store the data given the
         // current position
@@ -1014,158 +1342,96 @@
 
 
     /**
-     * Manage a BTree. The btree will be added and managed by this RecordManager. We will create a
-     * new RootPage for this added BTree, which will contain no data.
+     * Manage a B-tree. The btree will be added and managed by this RecordManager. We will create a
+     * new RootPage for this added B-tree, which will contain no data.<br/>
+     * This method is threadsafe.
      *
-     * @param btree The new BTree to manage.
+     * @param btree The new B-tree to manage.
+     * @throws BTreeAlreadyManagedException if the B-tree is already managed
+     * @throws IOException if there was a problem while accessing the file
      */
     public synchronized <K, V> void manage( BTree<K, V> btree ) throws BTreeAlreadyManagedException, IOException
     {
+        beginTransaction();
+
         manage( ( BTree<Object, Object> ) btree, NORMAL_BTREE );
+
+        commit();
     }
 
 
     /**
-     * works the same as @see #manage(BTree) except the given tree will not be linked to top level trees that will be
-     * loaded initially if the internalTree flag is set to true
+     * Managing a btree is a matter of storing an reference to the managed B-tree in the B-tree Of B-trees.
+     * We store a tuple of NameRevision (where revision is 0L) and a offset to the B-tree header.
+     * At the same time, we keep a track of the managed B-trees in a Map.
      *
-     * @param btree The new BTree to manage.
-     * @param internalTree flag indicating if this is an internal tree
+     * @param btree The new B-tree to manage.
+     * @param treeType flag indicating if this is an internal tree
      *
-     * @throws BTreeAlreadyManagedException
+     * @throws BTreeAlreadyManagedException If the B-tree is already managed
      * @throws IOException
      */
-    public synchronized <K, V> void manage( BTree<K, V> btree, boolean internalTree )
-        throws BTreeAlreadyManagedException,
-        IOException
+    public synchronized <K, V> void manage( BTree<K, V> btree, boolean treeType )
+        throws BTreeAlreadyManagedException, IOException
     {
-        LOG.debug( "Managing the btree {} which is an internam tree : {}", btree.getName(), internalTree );
+        LOG.debug( "Managing the btree {} which is an internam tree : {}", btree.getName(), treeType );
         BTreeFactory.setRecordManager( btree, this );
 
         String name = btree.getName();
 
-        if ( managedBTrees.containsKey( name ) )
+        if ( managedBtrees.containsKey( name ) )
         {
-            // There is already a BTree with this name in the recordManager...
-            LOG.error( "There is already a BTree named '{}' managed by this recordManager", name );
+            // There is already a B-tree with this name in the recordManager...
+            LOG.error( "There is already a B-tree named '{}' managed by this recordManager", name );
             throw new BTreeAlreadyManagedException( name );
         }
 
-        // Do not add the BTree if it's internal into the Map of managed btrees, otherwise we will
-        // not discard it when reloading a page wth internal btrees
-        if ( !internalTree )
-        {
-            managedBTrees.put( name, ( BTree<Object, Object> ) btree );
-        }
+        // Now, write the B-tree informations
+        long btreeInfoOffset = writeBtreeInfo( btree );
+        BTreeHeader<K, V> btreeHeader = ((AbstractBTree<K,V>)btree).getBtreeHeader();
+        ((PersistedBTree<K, V>)btree).setBtreeInfoOffset( btreeInfoOffset );
 
-        // We will add the newly managed BTree at the end of the header.
-        byte[] btreeNameBytes = Strings.getBytesUtf8( name );
-        byte[] keySerializerBytes = Strings.getBytesUtf8( btree.getKeySerializerFQCN() );
-        byte[] valueSerializerBytes = Strings.getBytesUtf8( btree.getValueSerializerFQCN() );
+        // Serialize the B-tree root page
+        Page<K, V> rootPage = btreeHeader.getRootPage();
 
-        int bufferSize =
-            INT_SIZE + // The name size
-                btreeNameBytes.length + // The name
-                INT_SIZE + // The keySerializerBytes size
-                keySerializerBytes.length + // The keySerializerBytes
-                INT_SIZE + // The valueSerializerBytes size
-                valueSerializerBytes.length + // The valueSerializerBytes
-                INT_SIZE + // The page size
-                LONG_SIZE + // The revision
-                LONG_SIZE + // the number of element
-                LONG_SIZE + // the nextBtree offset
-                LONG_SIZE + // The root offset
-                INT_SIZE; // The allowDuplicates flag
-
-        // Get the pageIOs we need to store the data. We may need more than one.
-        PageIO[] pageIos = getFreePageIOs( bufferSize );
-
-        // Store the BTree Offset into the BTree
-        long btreeOffset = pageIos[0].getOffset();
-        ( ( PersistedBTree<K, V> ) btree ).setBtreeOffset( btreeOffset );
-
-        // Now store the BTree data in the pages :
-        // - the BTree revision
-        // - the BTree number of elements
-        // - The RootPage offset
-        // - The next Btree offset
-        // - the BTree page size
-        // - the BTree name
-        // - the keySerializer FQCN
-        // - the valueSerializer FQCN
-        // - the flags that tell if the dups are allowed
-        // Starts at 0
-        long position = 0L;
-
-        // The BTree current revision
-        position = store( position, btree.getRevision(), pageIos );
-
-        // The nb elems in the tree
-        position = store( position, btree.getNbElems(), pageIos );
-
-        // Serialize the BTree root page
-        Page<K, V> rootPage = BTreeFactory.getRootPage( btree );
-
-        PageIO[] rootPageIos = serializePage( btree, btree.getRevision(), rootPage );
+        PageIO[] rootPageIos = serializePage( btree, btreeHeader.getRevision(), rootPage );
 
         // Get the reference on the first page
-        PageIO rootPageIo = rootPageIos[0];
+        long rootPageOffset =  rootPageIos[0].getOffset();
 
-        // Now, we can inject the BTree rootPage offset into the BTree header
-        position = store( position, rootPageIo.getOffset(), pageIos );
-        ( ( PersistedBTree<K, V> ) btree ).setRootPageOffset( rootPageIo.getOffset() );
-        ( ( PersistedLeaf<K, V> ) rootPage ).setOffset( rootPageIo.getOffset() );
+        // Store the rootPageOffset into the Btree header and into the rootPage
+        btreeHeader.setRootPageOffset( rootPageOffset );
+        ( ( PersistedLeaf<K, V> ) rootPage ).setOffset( rootPageOffset );
 
-        // The next BTree Header offset (-1L, as it's a new BTree)
-        position = store( position, NO_PAGE, pageIos );
-
-        // The BTree page size
-        position = store( position, btree.getPageSize(), pageIos );
-
-        // The tree name
-        position = store( position, btreeNameBytes, pageIos );
-
-        // The keySerializer FQCN
-        position = store( position, keySerializerBytes, pageIos );
-
-        // The valueSerialier FQCN
-        position = store( position, valueSerializerBytes, pageIos );
-
-        // The allowDuplicates flag
-        position = store( position, ( btree.isAllowDuplicates() ? 1 : 0 ), pageIos );
-
-        // And flush the pages to disk now
-        LOG.debug( "Flushing the newly managed '{}' btree header", btree.getName() );
-        flushPages( pageIos );
         LOG.debug( "Flushing the newly managed '{}' btree rootpage", btree.getName() );
         flushPages( rootPageIos );
 
-        // Now, if this added BTree is not the first BTree, we have to link it with the
-        // latest added BTree
-        if ( !internalTree )
+        // And the B-tree header
+        long btreeHeaderOffset = writeBtreeHeader( btree, btreeHeader );
+
+        // Now, if this is a new B-tree, add it to the B-tree of B-trees
+        if ( treeType != INTERNAL_BTREE )
         {
+            // Add the btree into the map of managed B-trees
+            managedBtrees.put( name, ( BTree<Object, Object> ) btree );
+            
+            // And in the Map of currentBtreeHeaders and newBtreeHeaders
+            currentBTreeHeaders.put( name, btreeHeader );
+            newBTreeHeaders.put( name, btreeHeader );
+
+            // We can safely increment the number of managed B-trees
             nbBtree++;
 
-            if ( lastAddedBTreeOffset != NO_PAGE )
-            {
-                // We have to update the nextBtreeOffset from the previous BTreeHeader
-                pageIos = readPageIOs( lastAddedBTreeOffset, LONG_SIZE + LONG_SIZE + LONG_SIZE + LONG_SIZE );
-                store( LONG_SIZE + LONG_SIZE + LONG_SIZE, btreeOffset, pageIos );
+            // Create the new NameRevision
+            NameRevision nameRevision = new NameRevision( name, 0L );
 
-                // Write the pages on disk
-                LOG.debug( "Updated the previous btree pointer on the added BTree {}", btree.getName() );
-                flushPages( pageIos );
-            }
-
-            lastAddedBTreeOffset = btreeOffset;
-
-            // Last, not least, update the number of managed BTrees in the header
-            updateRecordManagerHeader();
+            // Inject it into the B-tree of B-tree
+            btreeOfBtrees.insert( nameRevision, btreeHeaderOffset );
         }
 
         if ( LOG_CHECK.isDebugEnabled() )
         {
-            check();
+            MavibotInspector.check( this );
         }
     }
 
@@ -1352,7 +1618,7 @@
 
 
     /**
-     * Serialize a Leaf's Value. We store
+     * Serialize a Leaf's Value.
      */
     private <K, V> int serializeLeafValue( PersistedLeaf<K, V> leaf, int pos, List<byte[]> serializedData )
         throws IOException
@@ -1403,7 +1669,7 @@
                 serializedData.add( buffer );
                 dataSize += buffer.length;
 
-                // the BTree offset
+                // the B-tree offset
                 buffer = LongSerializer.serialize( ( ( PersistedValueHolder<V> ) valueHolder ).getOffset() );
                 serializedData.add( buffer );
                 dataSize += buffer.length;
@@ -1464,131 +1730,581 @@
 
 
     /**
-     * Update the header, injecting the following data :
+     * Update the RecordManager header, injecting the following data :
+     *
      * <pre>
-     * +---------------+
-     * | PageSize      | 4 bytes : The size of a physical page (default to 4096)
-     * +---------------+
-     * | NbTree        | 4 bytes : The number of managed BTrees (at least 1)
-     * +---------------+
-     * | FirstFree     | 8 bytes : The offset of the first free page
-     * +---------------+
-     * | currentBoB    | 1 byte : The current BoB in use
-     * +---------------+
-     * | BoB offset[0] | 8 bytes : The offset of the first BoB
-     * +---------------+
-     * | BoB offset[1] | 8 bytes : The offset of the second BoB
-     * +---------------+
+     * +---------------------+
+     * | PageSize            | 4 bytes : The size of a physical page (default to 4096)
+     * +---------------------+
+     * | NbTree              | 4 bytes : The number of managed B-trees (at least 1)
+     * +---------------------+
+     * | FirstFree           | 8 bytes : The offset of the first free page
+     * +---------------------+
+     * | current BoB offset  | 8 bytes : The offset of the current B-tree of B-trees
+     * +---------------------+
+     * | previous BoB offset | 8 bytes : The offset of the previous B-tree of B-trees
+     * +---------------------+
+     * | current CP offset   | 8 bytes : The offset of the current CopiedPages B-tree
+     * +---------------------+
+     * | previous CP offset  | 8 bytes : The offset of the previous CopiedPages B-tree
+     * +---------------------+
      * </pre>
      */
-    public void updateRecordManagerHeader() throws IOException
+    public void updateRecordManagerHeader()
     {
         // The page size
-        HEADER_BYTES[0] = ( byte ) ( pageSize >>> 24 );
-        HEADER_BYTES[1] = ( byte ) ( pageSize >>> 16 );
-        HEADER_BYTES[2] = ( byte ) ( pageSize >>> 8 );
-        HEADER_BYTES[3] = ( byte ) ( pageSize );
+        int position = writeData( RECORD_MANAGER_HEADER_BYTES, 0, pageSize );
 
-        // The number of managed BTree (currently we have only one : the discardedPage BTree
-        HEADER_BYTES[4] = ( byte ) ( nbBtree >>> 24 );
-        HEADER_BYTES[5] = ( byte ) ( nbBtree >>> 16 );
-        HEADER_BYTES[6] = ( byte ) ( nbBtree >>> 8 );
-        HEADER_BYTES[7] = ( byte ) ( nbBtree );
+        // The number of managed B-tree
+        position = writeData( RECORD_MANAGER_HEADER_BYTES, position, nbBtree );
 
         // The first free page
-        HEADER_BYTES[8] = ( byte ) ( firstFreePage >>> 56 );
-        HEADER_BYTES[9] = ( byte ) ( firstFreePage >>> 48 );
-        HEADER_BYTES[10] = ( byte ) ( firstFreePage >>> 40 );
-        HEADER_BYTES[11] = ( byte ) ( firstFreePage >>> 32 );
-        HEADER_BYTES[12] = ( byte ) ( firstFreePage >>> 24 );
-        HEADER_BYTES[13] = ( byte ) ( firstFreePage >>> 16 );
-        HEADER_BYTES[14] = ( byte ) ( firstFreePage >>> 8 );
-        HEADER_BYTES[15] = ( byte ) ( firstFreePage );
+        position = writeData( RECORD_MANAGER_HEADER_BYTES, position, firstFreePage );
 
-        // The offset of the first BoB
-        HEADER_BYTES[17] = ( byte ) ( bobOldRevision >>> 56 );
-        HEADER_BYTES[18] = ( byte ) ( bobOldRevision >>> 48 );
-        HEADER_BYTES[19] = ( byte ) ( bobOldRevision >>> 40 );
-        HEADER_BYTES[20] = ( byte ) ( bobOldRevision >>> 32 );
-        HEADER_BYTES[21] = ( byte ) ( bobOldRevision >>> 24 );
-        HEADER_BYTES[22] = ( byte ) ( bobOldRevision >>> 16 );
-        HEADER_BYTES[23] = ( byte ) ( bobOldRevision >>> 8 );
-        HEADER_BYTES[24] = ( byte ) ( bobOldRevision );
+        // The offset of the current B-tree of B-trees
+        position = writeData( RECORD_MANAGER_HEADER_BYTES, position, currentBtreeOfBtreesOffset );
 
-        // The offset of the second BoB
-        HEADER_BYTES[17] = ( byte ) ( bobCurrentRevision >>> 56 );
-        HEADER_BYTES[18] = ( byte ) ( bobCurrentRevision >>> 48 );
-        HEADER_BYTES[19] = ( byte ) ( bobCurrentRevision >>> 40 );
-        HEADER_BYTES[20] = ( byte ) ( bobCurrentRevision >>> 32 );
-        HEADER_BYTES[21] = ( byte ) ( bobCurrentRevision >>> 24 );
-        HEADER_BYTES[22] = ( byte ) ( bobCurrentRevision >>> 16 );
-        HEADER_BYTES[23] = ( byte ) ( bobCurrentRevision >>> 8 );
-        HEADER_BYTES[24] = ( byte ) ( bobCurrentRevision );
+        // The offset of the copied pages B-tree
+        position = writeData( RECORD_MANAGER_HEADER_BYTES, position, previousBtreeOfBtreesOffset );
 
-        // Write the header on disk
-        HEADER_BUFFER.put( HEADER_BYTES );
-        HEADER_BUFFER.flip();
+        // The offset of the current B-tree of B-trees
+        position = writeData( RECORD_MANAGER_HEADER_BYTES, position, currentCopiedPagesBtreeOffset );
 
-        LOG.debug( "Update RM header, FF : {}", firstFreePage );
-        fileChannel.write( HEADER_BUFFER, 0 );
-        HEADER_BUFFER.clear();
+        // The offset of the copied pages B-tree
+        position = writeData( RECORD_MANAGER_HEADER_BYTES, position, previousCopiedPagesBtreeOffset );
+
+        // Write the RecordManager header on disk
+        RECORD_MANAGER_HEADER_BUFFER.put( RECORD_MANAGER_HEADER_BYTES );
+        RECORD_MANAGER_HEADER_BUFFER.flip();
+
+        LOG.debug( "Update RM header" );
+
+        if ( LOG_PAGES.isDebugEnabled() )
+        {
+            StringBuilder sb = new StringBuilder();
+
+            sb.append( "First free page     : 0x" ).append( Long.toHexString( firstFreePage ) ).append( "\n" );
+            sb.append( "Current BOB header  : 0x" ).append( Long.toHexString( currentBtreeOfBtreesOffset ) ).append( "\n" );
+            sb.append( "Previous BOB header : 0x" ).append( Long.toHexString( previousBtreeOfBtreesOffset ) ).append( "\n" );
+            sb.append( "Current CPB header  : 0x" ).append( Long.toHexString( currentCopiedPagesBtreeOffset ) ).append( "\n" );
+            sb.append( "Previous CPB header : 0x" ).append( Long.toHexString( previousCopiedPagesBtreeOffset ) ).append( "\n" );
+
+            if ( firstFreePage != NO_PAGE )
+            {
+                long freePage = firstFreePage;
+                sb.append( "free pages list : " );
+
+                boolean isFirst = true;
+
+                while ( freePage != NO_PAGE )
+                {
+                    if ( isFirst )
+                    {
+                        isFirst = false;
+                    }
+                    else
+                    {
+                        sb.append( " -> " );
+                    }
+
+                    sb.append( "0x" ).append( Long.toHexString( freePage ) );
+
+                    try
+                    {
+                        PageIO[] freePageIO = readPageIOs( freePage, 8 );
+
+                        freePage = freePageIO[0].getNextPage();
+                    }
+                    catch ( EndOfFileExceededException e )
+                    {
+                        // TODO Auto-generated catch block
+                        e.printStackTrace();
+                    }
+                    catch ( IOException e )
+                    {
+                        // TODO Auto-generated catch block
+                        e.printStackTrace();
+                    }
+                }
+
+            }
+
+            LOG_PAGES.debug( "Update RM Header : \n{}", sb.toString() );
+        }
+
+        try
+        {
+            fileChannel.write( RECORD_MANAGER_HEADER_BUFFER, 0 );
+        }
+        catch ( IOException ioe )
+        {
+            throw new FileException( ioe.getMessage() );
+        }
+
+        RECORD_MANAGER_HEADER_BUFFER.clear();
+
+        // Reset the old versions
+        previousBtreeOfBtreesOffset = -1L;
+        previousCopiedPagesBtreeOffset = -1L;
 
         nbUpdateRMHeader.incrementAndGet();
     }
 
 
     /**
-     * Update the BTree header after a BTree modification. This will make the latest modification
-     * visible.
-     * We update the following fields :
-     * <ul>
-     * <li>the revision</li>
-     * <li>the number of elements</li>
-     * <li>the reference to the current BTree revisions</li>
-     * <li>the reference to the old BTree revisions</li>
-     * </ul>
-     * @param btree
-     * @throws IOException
-     * @throws EndOfFileExceededException
+     * Update the RecordManager header, injecting the following data :
+     *
+     * <pre>
+     * +---------------------+
+     * | PageSize            | 4 bytes : The size of a physical page (default to 4096)
+     * +---------------------+
+     * | NbTree              | 4 bytes : The number of managed B-trees (at least 1)
+     * +---------------------+
+     * | FirstFree           | 8 bytes : The offset of the first free page
+     * +---------------------+
+     * | current BoB offset  | 8 bytes : The offset of the current B-tree of B-trees
+     * +---------------------+
+     * | previous BoB offset | 8 bytes : The offset of the previous B-tree of B-trees
+     * +---------------------+
+     * | current CP offset   | 8 bytes : The offset of the current CopiedPages B-tree
+     * +---------------------+
+     * | previous CP offset  | 8 bytes : The offset of the previous CopiedPages B-tree
+     * +---------------------+
+     * </pre>
      */
-    /* No qualifier*/<K, V> void updateBtreeHeader( BTree<K, V> btree, long rootPageOffset )
-        throws EndOfFileExceededException,
-        IOException
+    public void updateRecordManagerHeader( long newBtreeOfBtreesOffset, long newCopiedPageBtreeOffset )
     {
-        // Read the pageIOs associated with this BTree
-        long offset = ( ( PersistedBTree<K, V> ) btree ).getBtreeOffset();
-        long headerSize = LONG_SIZE + LONG_SIZE + LONG_SIZE;
-
-        PageIO[] pageIos = readPageIOs( offset, headerSize );
-
-        // Now, update the revision
-        long position = 0;
-
-        position = store( position, btree.getRevision(), pageIos );
-        position = store( position, btree.getNbElems(), pageIos );
-        position = store( position, rootPageOffset, pageIos );
-
-        // Write the pages on disk
-        if ( LOG.isDebugEnabled() )
+        if ( newBtreeOfBtreesOffset != -1L )
         {
-            LOG.debug( "-----> Flushing the '{}' BTreeHeader", btree.getName() );
-            LOG.debug( "  revision : " + btree.getRevision() + ", NbElems : " + btree.getNbElems() + ", root offset : "
-                + rootPageOffset );
+            previousBtreeOfBtreesOffset = currentBtreeOfBtreesOffset;
+            currentBtreeOfBtreesOffset = newBtreeOfBtreesOffset;
         }
 
-        flushPages( pageIos );
-
-        nbUpdateBTreeHeader.incrementAndGet();
-
-        if ( LOG_CHECK.isDebugEnabled() )
+        if ( newCopiedPageBtreeOffset != -1L )
         {
-            check();
+            previousCopiedPagesBtreeOffset = currentCopiedPagesBtreeOffset;
+            currentCopiedPagesBtreeOffset = newCopiedPageBtreeOffset;
         }
     }
 
 
     /**
-     * Write the pages in the disk, either at the end of the file, or at
+     * Inject an int into a byte[] at a given position.
+     */
+    private int writeData( byte[] buffer, int position, int value )
+    {
+        RECORD_MANAGER_HEADER_BYTES[position] = ( byte ) ( value >>> 24 );
+        RECORD_MANAGER_HEADER_BYTES[position+1] = ( byte ) ( value >>> 16 );
+        RECORD_MANAGER_HEADER_BYTES[position+2] = ( byte ) ( value >>> 8 );
+        RECORD_MANAGER_HEADER_BYTES[position+3] = ( byte ) ( value );
+
+        return position + 4;
+    }
+
+
+    /**
+     * Inject a long into a byte[] at a given position.
+     */
+    private int writeData( byte[] buffer, int position, long value )
+    {
+        RECORD_MANAGER_HEADER_BYTES[position] = ( byte ) ( value >>> 56 );
+        RECORD_MANAGER_HEADER_BYTES[position+1] = ( byte ) ( value >>> 48 );
+        RECORD_MANAGER_HEADER_BYTES[position+2] = ( byte ) ( value >>> 40 );
+        RECORD_MANAGER_HEADER_BYTES[position+3] = ( byte ) ( value >>> 32 );
+        RECORD_MANAGER_HEADER_BYTES[position+4] = ( byte ) ( value >>> 24 );
+        RECORD_MANAGER_HEADER_BYTES[position+5] = ( byte ) ( value >>> 16 );
+        RECORD_MANAGER_HEADER_BYTES[position+6] = ( byte ) ( value >>> 8 );
+        RECORD_MANAGER_HEADER_BYTES[position+7] = ( byte ) ( value );
+
+        return position + 8;
+    }
+
+
+    /**
+     * Add a new <btree, revision> tuple into the B-tree of B-trees.
+     *
+     * @param name The B-tree name
+     * @param revision The B-tree revision
+     * @param btreeHeaderOffset The B-tree offset
+     * @throws IOException If the update failed
+     */
+    /* no qualifier */ <K, V> void addInBtreeOfBtrees( String name, long revision, long btreeHeaderOffset ) throws IOException
+    {
+        checkOffset( btreeHeaderOffset );
+        NameRevision nameRevision = new NameRevision( name, revision );
+
+        btreeOfBtrees.insert( nameRevision, btreeHeaderOffset );
+
+        // Update the B-tree of B-trees offset
+        currentBtreeOfBtreesOffset = getBTreeHeader( BTREE_OF_BTREES_NAME ).getBTreeHeaderOffset();
+    }
+
+
+    /**
+     * Add a new <btree, revision> tuple into the CopiedPages B-tree.
+     *
+     * @param name The B-tree name
+     * @param revision The B-tree revision
+     * @param btreeHeaderOffset The B-tree offset
+     * @throws IOException If the update failed
+     */
+    /* no qualifier */ <K, V> void addInCopiedPagesBtree( String name, long revision, List<Page<K, V>> pages ) throws IOException
+    {
+        RevisionName revisionName = new RevisionName( revision, name );
+
+        long[] pageOffsets = new long[pages.size()];
+        int pos = 0;
+
+        for ( Page<K, V> page : pages )
+        {
+            pageOffsets[pos++] = ((AbstractPage<K, V>)page).getOffset();
+        }
+
+        copiedPageBtree.insert( revisionName, pageOffsets );
+
+        // Update the CopiedPageBtree offset
+        currentCopiedPagesBtreeOffset = ((AbstractBTree<RevisionName, long[]>)copiedPageBtree).getBtreeHeader().getBTreeHeaderOffset();
+    }
+
+
+    /**
+     * Internal method used to update the B-tree of B-trees offset
+     * @param btreeOfBtreesOffset The new offset
+     */
+    /* no qualifier */ void setBtreeOfBtreesOffset( long btreeOfBtreesOffset )
+    {
+        checkOffset( btreeOfBtreesOffset );
+        this.currentBtreeOfBtreesOffset = btreeOfBtreesOffset;
+    }
+
+
+    /**
+     * Write the B-tree header on disk. We will write the following informations :
+     * <pre>
+     * +------------+
+     * | revision   | The B-tree revision
+     * +------------+
+     * | nbElems    | The B-tree number of elements
+     * +------------+
+     * | rootPage   | The root page offset
+     * +------------+
+     * | BtreeInfo  | The B-tree info offset
+     * +------------+
+     * </pre>
+     * @param btree The B-tree which header has to be written
+     * @param btreeInfoOffset The offset of the B-tree informations
+     * @return The B-tree header offset
+     * @throws IOException If we weren't able to write the B-tree header
+     */
+    /* no qualifier */ <K, V> long writeBtreeHeader( BTree<K, V> btree, BTreeHeader<K, V> btreeHeader ) throws IOException
+    {
+        int bufferSize =
+            LONG_SIZE +                     // The revision
+            LONG_SIZE +                     // the number of element
+            LONG_SIZE +                     // The root page offset
+            LONG_SIZE;                      // The B-tree info page offset
+
+        // Get the pageIOs we need to store the data. We may need more than one.
+        PageIO[] btreeHeaderPageIos = getFreePageIOs( bufferSize );
+
+        // Store the B-tree header Offset into the B-tree
+        long btreeHeaderOffset = btreeHeaderPageIos[0].getOffset();
+
+        // Now store the B-tree data in the pages :
+        // - the B-tree revision
+        // - the B-tree number of elements
+        // - the B-tree root page offset
+        // - the B-tree info page offset
+        // Starts at 0
+        long position = 0L;
+
+        // The B-tree current revision
+        position = store( position, btreeHeader.getRevision(), btreeHeaderPageIos );
+
+        // The nb elems in the tree
+        position = store( position, btreeHeader.getNbElems(), btreeHeaderPageIos );
+
+
+        // Now, we can inject the B-tree rootPage offset into the B-tree header
+        position = store( position, btreeHeader.getRootPageOffset(), btreeHeaderPageIos );
+
+        // The B-tree info page offset
+        position = store( position, ((PersistedBTree<K, V>)btree).getBtreeInfoOffset(), btreeHeaderPageIos );
+
+        // And flush the pages to disk now
+        LOG.debug( "Flushing the newly managed '{}' btree header", btree.getName() );
+
+        if ( LOG_PAGES.isDebugEnabled() )
+        {
+            LOG_PAGES.debug( "Writing BTreeHeader revision {} for {}", btreeHeader.getRevision(), btree.getName() );
+            StringBuilder sb = new StringBuilder();
+
+            sb.append( "Offset : " ).append( Long.toHexString( btreeHeaderOffset ) ).append( "\n" );
+            sb.append( "    Revision : " ).append( btreeHeader.getRevision() ).append( "\n" );
+            sb.append( "    NbElems  : " ).append( btreeHeader.getNbElems() ).append( "\n" );
+            sb.append( "    RootPage : 0x" ).append( Long.toHexString( btreeHeader.getRootPageOffset() ) ).append( "\n" );
+            sb.append( "    Info     : 0x" ).append( Long.toHexString( ((PersistedBTree<K, V>)btree).getBtreeInfoOffset() ) ).append( "\n" );
+
+            LOG_PAGES.debug( "Btree Header[{}]\n{}", btreeHeader.getRevision(), sb.toString() );
+        }
+
+        flushPages( btreeHeaderPageIos );
+
+        btreeHeader.setBTreeHeaderOffset( btreeHeaderOffset );
+
+        return btreeHeaderOffset;
+    }
+
+
+    /**
+     * Write the B-tree informations on disk. We will write the following informations :
+     * <pre>
+     * +------------+
+     * | pageSize   | The B-tree page size (ie, the number of elements per page max)
+     * +------------+
+     * | nameSize   | The B-tree name size
+     * +------------+
+     * | name       | The B-tree name
+     * +------------+
+     * | keySerSize | The keySerializer FQCN size
+     * +------------+
+     * | keySerFQCN | The keySerializer FQCN
+     * +------------+
+     * | valSerSize | The Value serializer FQCN size
+     * +------------+
+     * | valSerKQCN | The valueSerializer FQCN
+     * +------------+
+     * | dups       | The flags that tell if the dups are allowed
+     * +------------+
+     * </pre>
+     * @param btree The B-tree which header has to be written
+     * @return The B-tree header offset
+     * @throws IOException If we weren't able to write the B-tree header
+     */
+    private <K, V> long writeBtreeInfo( BTree<K, V> btree ) throws IOException
+    {
+        // We will add the newly managed B-tree at the end of the header.
+        byte[] btreeNameBytes = Strings.getBytesUtf8( btree.getName() );
+        byte[] keySerializerBytes = Strings.getBytesUtf8( btree.getKeySerializerFQCN() );
+        byte[] valueSerializerBytes = Strings.getBytesUtf8( btree.getValueSerializerFQCN() );
+
+        int bufferSize =
+            INT_SIZE +                      // The page size
+            INT_SIZE +                      // The name size
+            btreeNameBytes.length +         // The name
+            INT_SIZE +                      // The keySerializerBytes size
+            keySerializerBytes.length +     // The keySerializerBytes
+            INT_SIZE +                      // The valueSerializerBytes size
+            valueSerializerBytes.length +   // The valueSerializerBytes
+            INT_SIZE;                       // The allowDuplicates flag
+
+        // Get the pageIOs we need to store the data. We may need more than one.
+        PageIO[] btreeHeaderPageIos = getFreePageIOs( bufferSize );
+
+        // Keep the B-tree header Offset into the B-tree
+        long btreeInfoOffset = btreeHeaderPageIos[0].getOffset();
+
+        // Now store the B-tree information data in the pages :
+        // - the B-tree page size
+        // - the B-tree name
+        // - the keySerializer FQCN
+        // - the valueSerializer FQCN
+        // - the flags that tell if the dups are allowed
+        // Starts at 0
+        long position = 0L;
+
+        // The B-tree page size
+        position = store( position, btree.getPageSize(), btreeHeaderPageIos );
+
+        // The tree name
+        position = store( position, btreeNameBytes, btreeHeaderPageIos );
+
+        // The keySerializer FQCN
+        position = store( position, keySerializerBytes, btreeHeaderPageIos );
+
+        // The valueSerialier FQCN
+        position = store( position, valueSerializerBytes, btreeHeaderPageIos );
+
+        // The allowDuplicates flag
+        position = store( position, ( btree.isAllowDuplicates() ? 1 : 0 ), btreeHeaderPageIos );
+
+        // And flush the pages to disk now
+        LOG.debug( "Flushing the newly managed '{}' btree header", btree.getName() );
+        flushPages( btreeHeaderPageIos );
+
+        return btreeInfoOffset;
+    }
+
+
+    /**
+     * Update the B-tree header after a B-tree modification. This will make the latest modification
+     * visible.<br/>
+     * We update the following fields :
+     * <ul>
+     * <li>the revision</li>
+     * <li>the number of elements</li>
+     * <li>the B-tree root page offset</li>
+     * </ul>
+     * <br/>
+     * As a result, a new version of the BtreHeader will be created, which will replace the previous
+     * B-tree header
+     * @param btree TheB-tree to update
+     * @param btreeHeaderOffset The offset of the modified btree header
+     * @return The offset of the new B-tree Header
+     * @throws IOException If we weren't able to write the file on disk
+     * @throws EndOfFileExceededException If we tried to write after the end of the file
+     */
+    /* no qualifier */ <K, V> long updateBtreeHeader( BTree<K, V> btree, long btreeHeaderOffset )
+        throws EndOfFileExceededException, IOException
+    {
+        return updateBtreeHeader( btree, btreeHeaderOffset, false );
+    }
+
+
+    /**
+     * Update the B-tree header after a B-tree modification. This will make the latest modification
+     * visible.<br/>
+     * We update the following fields :
+     * <ul>
+     * <li>the revision</li>
+     * <li>the number of elements</li>
+     * <li>the reference to the current B-tree revisions</li>
+     * <li>the reference to the old B-tree revisions</li>
+     * </ul>
+     * <br/>
+     * As a result, we new version of the BtreHeader will be created
+     * @param btree The B-tree to update
+     * @param btreeHeaderOffset The offset of the modified btree header
+     * @return The offset of the new B-tree Header if it has changed (ie, when the onPlace flag is set to true)
+     * @throws IOException
+     * @throws EndOfFileExceededException
+     */
+    /* no qualifier */ <K, V> void updateBtreeHeaderOnPlace( BTree<K, V> btree, long btreeHeaderOffset )
+        throws EndOfFileExceededException,
+        IOException
+    {
+        updateBtreeHeader( btree, btreeHeaderOffset, true );
+    }
+
+
+    /**
+     * Update the B-tree header after a B-tree modification. This will make the latest modification
+     * visible.<br/>
+     * We update the following fields :
+     * <ul>
+     * <li>the revision</li>
+     * <li>the number of elements</li>
+     * <li>the reference to the current B-tree revisions</li>
+     * <li>the reference to the old B-tree revisions</li>
+     * </ul>
+     * <br/>
+     * As a result, a new version of the BtreHeader will be created, which may replace the previous
+     * B-tree header (if the onPlace flag is set to true) or a new set of pageIos will contain the new
+     * version.
+     *
+     * @param btree The B-tree to update
+     * @param rootPageOffset The offset of the modified rootPage
+     * @param onPlace Tells if we modify the B-tree on place, or if we create a copy
+     * @return The offset of the new B-tree Header if it has changed (ie, when the onPlace flag is set to true)
+     * @throws EndOfFileExceededException If we tried to write after the end of the file
+     * @throws IOException If tehre were some error while writing the data on disk
+     */
+    private <K, V> long updateBtreeHeader( BTree<K, V> btree, long btreeHeaderOffset, boolean onPlace )
+        throws EndOfFileExceededException, IOException
+    {
+        // Read the pageIOs associated with this B-tree
+        PageIO[] pageIos;
+        long newBtreeHeaderOffset = NO_PAGE;
+        long offset = ( ( PersistedBTree<K, V> ) btree ).getBtreeOffset();
+
+        if ( onPlace )
+        {
+            // We just have to update the existing BTreeHeader
+            long headerSize = LONG_SIZE + LONG_SIZE + LONG_SIZE;
+
+            pageIos = readPageIOs( offset, headerSize );
+
+            // Now, update the revision
+            long position = 0;
+
+            position = store( position, btree.getRevision(), pageIos );
+            position = store( position, btree.getNbElems(), pageIos );
+            position = store( position, btreeHeaderOffset, pageIos );
+
+            // Write the pages on disk
+            if ( LOG.isDebugEnabled() )
+            {
+                LOG.debug( "-----> Flushing the '{}' B-treeHeader", btree.getName() );
+                LOG.debug( "  revision : " + btree.getRevision() + ", NbElems : " + btree.getNbElems() + ", btreeHeader offset : 0x"
+                    + Long.toHexString( btreeHeaderOffset ) );
+            }
+
+            // Get new place on disk to store the modified BTreeHeader if it's not onPlace
+            // Rewrite the pages at the same place
+            LOG.debug( "Rewriting the B-treeHeader on place for B-tree " + btree.getName() );
+            flushPages( pageIos );
+        }
+        else
+        {
+            // We have to read and copy the existing BTreeHeader and to create a new one
+            pageIos = readPageIOs( offset, Long.MAX_VALUE );
+
+            // Now, copy every read page
+            PageIO[] newPageIOs = new PageIO[pageIos.length];
+            int pos = 0;
+
+            for ( PageIO pageIo : pageIos )
+            {
+                // Fetch a free page
+                newPageIOs[pos] = fetchNewPage();
+
+                // keep a track of the allocated and copied pages so that we can
+                // free them when we do a commit or rollback, if the btree is an management one
+                if ( ( btree.getType() == BTreeTypeEnum.BTREE_OF_BTREES ) || ( btree.getType() == BTreeTypeEnum.COPIED_PAGES_BTREE ) )
+                {
+                    freedPages.add( pageIo );
+                    allocatedPages.add( newPageIOs[pos] );
+                }
+
+                pageIo.copy( newPageIOs[pos] );
+
+                if ( pos > 0 )
+                {
+                    newPageIOs[pos - 1].setNextPage( newPageIOs[pos].getOffset() );
+                }
+
+                pos++;
+            }
+
+            // store the new btree header offset
+            // and update the revision
+            long position = 0;
+
+            position = store( position, btree.getRevision(), newPageIOs );
+            position = store( position, btree.getNbElems(), newPageIOs );
+            position = store( position, btreeHeaderOffset, newPageIOs );
+
+            // Get new place on disk to store the modified BTreeHeader if it's not onPlace
+            // Flush the new B-treeHeader on disk
+            LOG.debug( "Rewriting the B-treeHeader on place for B-tree " + btree.getName() );
+            flushPages( newPageIOs );
+
+            newBtreeHeaderOffset = newPageIOs[0].getOffset();
+        }
+
+        nbUpdateBtreeHeader.incrementAndGet();
+
+        if ( LOG_CHECK.isDebugEnabled() )
+        {
+            MavibotInspector.check( this );
+        }
+
+        return newBtreeHeaderOffset;
+    }
+
+
+    /**
+     * Write the pages on disk, either at the end of the file, or at
      * the position they were taken from.
      *
      * @param pageIos The list of pages to write
@@ -1660,7 +2376,7 @@
      * @param position The position in a virtual byte[] if all the pages were contiguous
      * @param bytes The byte[] to serialize
      * @param pageIos The pageIOs we have to store the data in
-     * @return The new position
+     * @return The new offset
      */
     private long store( long position, byte[] bytes, PageIO... pageIos )
     {
@@ -1729,7 +2445,7 @@
      * @param position The position in a virtual byte[] if all the pages were contiguous
      * @param bytes The byte[] to serialize
      * @param pageIos The pageIOs we have to store the data in
-     * @return The new position
+     * @return The new offset
      */
     private long storeRaw( long position, byte[] bytes, PageIO... pageIos )
     {
@@ -1801,7 +2517,7 @@
      * @param position The position in a virtual byte[] if all the pages were contiguous
      * @param value The int to serialize
      * @param pageIos The pageIOs we have to store the data in
-     * @return The new position
+     * @return The new offset
      */
     private long store( long position, int value, PageIO... pageIos )
     {
@@ -1876,7 +2592,7 @@
      * @param position The position in a virtual byte[] if all the pages were contiguous
      * @param value The long to serialize
      * @param pageIos The pageIOs we have to store the data in
-     * @return The new position
+     * @return The new offset
      */
     private long store( long position, long value, PageIO... pageIos )
     {
@@ -1977,10 +2693,9 @@
 
 
     /**
-     * Stores a new page on disk. We will add the modified page into the tree of copied pages.
-     * The new page is serialized and saved on disk.
+     * Write the page in a serialized form.
      *
-     * @param btree The persistedBTree we will create a new PageHolder for
+     * @param btree The persistedBtree we will create a new PageHolder for
      * @param newPage The page to write on disk
      * @param newRevision The page's revision
      * @return A PageHolder containing the copied page
@@ -1992,7 +2707,12 @@
         // We first need to save the new page on disk
         PageIO[] pageIos = serializePage( btree, newRevision, newPage );
 
-        LOG.debug( "Write data for '{}' btree ", btree.getName() );
+        if ( LOG_PAGES.isDebugEnabled() )
+        {
+            LOG_PAGES.debug( "Write data for '{}' btree", btree.getName()  );
+
+            logPageIos( pageIos );
+        }
 
         // Write the page on disk
         flushPages( pageIos );
@@ -2005,13 +2725,69 @@
 
         if ( LOG_CHECK.isDebugEnabled() )
         {
-            check();
+            MavibotInspector.check( this );
         }
 
         return pageHolder;
     }
 
 
+    /* No qualifier */ static void logPageIos( PageIO[] pageIos )
+    {
+        int pageNb = 0;
+
+        for ( PageIO pageIo : pageIos )
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.append( "PageIO[" ).append( pageNb ).append( "]:0x" );
+            sb.append( Long.toHexString( pageIo.getOffset() ) ).append( "/");
+            sb.append( pageIo.getSize() );
+            pageNb++;
+
+            ByteBuffer data = pageIo.getData();
+
+            int position = data.position();
+            byte[] bytes = new byte[(int)pageIo.getSize() + 12];
+
+            data.get( bytes );
+            data.position( position );
+            int pos = 0;
+
+            for ( byte b : bytes )
+            {
+                int mod = pos%16;
+
+                switch ( mod )
+                {
+                    case 0:
+                        sb.append( "\n    " );
+                        // No break
+                    case 4:
+                    case 8:
+                    case 12:
+                        sb.append( " " );
+                    case 1:
+                    case 2:
+                    case 3:
+                    case 5:
+                    case 6:
+                    case 7:
+                    case 9:
+                    case 10:
+                    case 11:
+                    case 13:
+                    case 14:
+                    case 15:
+                        sb.append( Strings.dumpByte( b ) ).append( " " );
+                }
+                pos++;
+            }
+
+            LOG_PAGES.debug( sb.toString() );
+        }
+    }
+
+
     /**
      * Compute the number of pages needed to store some specific size of data.
      *
@@ -2053,7 +2829,8 @@
 
 
     /**
-     * Get as many pages as needed to store the data of the given size
+     * Get as many pages as needed to store the data of the given size. The returned
+     * PageIOs are all linked together.
      *
      * @param dataSize The data size
      * @return An array of pages, enough to store the full data
@@ -2094,6 +2871,8 @@
      */
     private PageIO fetchNewPage() throws IOException
     {
+        //dumpFreePages( firstFreePage );
+
         if ( firstFreePage == NO_PAGE )
         {
             nbCreatedPages.incrementAndGet();
@@ -2144,8 +2923,10 @@
      * @param offset The position in the file
      * @return The found page
      */
-    private PageIO fetchPage( long offset ) throws IOException, EndOfFileExceededException
+    /* no qualifier */ PageIO fetchPage( long offset ) throws IOException, EndOfFileExceededException
     {
+        checkOffset( offset );
+
         if ( fileChannel.size() < offset + pageSize )
         {
             // Error : we are past the end of the file
@@ -2178,14 +2959,20 @@
     }
 
 
-    public void setPageSize( int pageSize )
+    /**
+     * Set the page size, ie the number of bytes a page can store.
+     *
+     * @param pageSize The number of bytes for a page
+     */
+    /* no qualifier */ void setPageSize( int pageSize )
     {
-        if ( this.pageSize != -1 )
+        if ( this.pageSize >= 13 )
         {
+            this.pageSize = pageSize;
         }
         else
         {
-            this.pageSize = pageSize;
+            this.pageSize = DEFAULT_PAGE_SIZE;
         }
     }
 
@@ -2195,22 +2982,30 @@
      */
     public void close() throws IOException
     {
-        // TODO : we must wait for the last write to finish
+        beginTransaction();
 
-        for ( BTree<Object, Object> tree : managedBTrees.values() )
+        // Close all the managed B-trees
+        for ( BTree<Object, Object> tree : managedBtrees.values() )
         {
             tree.close();
         }
 
-        managedBTrees.clear();
+        // Close the management B-trees
+        copiedPageBtree.close();
+        btreeOfBtrees.close();
+
+        managedBtrees.clear();
 
         // Write the data
         fileChannel.force( true );
 
         // And close the channel
         fileChannel.close();
+
+        commit();
     }
 
+
     /** Hex chars */
     private static final byte[] HEX_CHAR = new byte[]
         { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
@@ -2248,8 +3043,6 @@
         System.out.println( " 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F " );
         System.out.println( "+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+" );
 
-        int position = buffer.position();
-
         for ( int i = 0; i < buffer.limit(); i += 16 )
         {
             System.out.print( "|" );
@@ -2279,87 +3072,267 @@
      * Dump the RecordManager file
      * @throws IOException
      */
-    public void dump() throws IOException
+    public void dump()
     {
-        RandomAccessFile randomFile = new RandomAccessFile( file, "r" );
-        FileChannel fileChannel = randomFile.getChannel();
+        System.out.println( "/---------------------------- Dump ----------------------------\\" );
 
-        ByteBuffer header = ByteBuffer.allocate( HEADER_SIZE );
-
-        // load the header
-        fileChannel.read( header );
-
-        header.rewind();
-
-        // The page size
-        int pageSize = header.getInt();
-
-        // The number of managed BTrees
-        int nbBTree = header.getInt();
-
-        // The first and last free page
-        long firstFreePage = header.getLong();
-
-        if ( LOG.isDebugEnabled() )
+        try
         {
-            LOG.debug( "RecordManager" );
-            LOG.debug( "-------------" );
-            LOG.debug( "  Header " );
-            LOG.debug( "    '{}'", Strings.dumpBytes( header.array() ) );
-            LOG.debug( "    page size : {}", pageSize );
-            LOG.debug( "    nbTree : {}", nbBTree );
-            LOG.debug( "    firstFreePage : {}", firstFreePage );
+            RandomAccessFile randomFile = new RandomAccessFile( file, "r" );
+            FileChannel fileChannel = randomFile.getChannel();
+
+            ByteBuffer recordManagerHeader = ByteBuffer.allocate( RECORD_MANAGER_HEADER_SIZE );
+
+            // load the RecordManager header
+            fileChannel.read( recordManagerHeader );
+
+            recordManagerHeader.rewind();
+
+            // The page size
+            long fileSize = fileChannel.size();
+            int pageSize = recordManagerHeader.getInt();
+            long nbPages = fileSize / pageSize;
+
+            // The number of managed B-trees
+            int nbBtree = recordManagerHeader.getInt();
+
+            // The first free page
+            long firstFreePage = recordManagerHeader.getLong();
+
+            // The current B-tree of B-trees
+            long currentBtreeOfBtreesPage = recordManagerHeader.getLong();
+
+            // The previous B-tree of B-trees
+            long previousBtreeOfBtreesPage = recordManagerHeader.getLong();
+
+            // The current CopiedPages B-tree
+            long currentCopiedPagesBtreePage = recordManagerHeader.getLong();
+
+            // The previous CopiedPages B-tree
+            long previousCopiedPagesBtreePage = recordManagerHeader.getLong();
+
+            System.out.println( "  RecordManager" );
+            System.out.println( "  -------------" );
+            System.out.println( "  Size = 0x" + Long.toHexString( fileSize ) );
+            System.out.println( "  NbPages = " + nbPages );
+            System.out.println( "    Header " );
+            System.out.println( "      page size : " + pageSize );
+            System.out.println( "      nbTree : " + nbBtree );
+            System.out.println( "      firstFreePage : 0x" + Long.toHexString( firstFreePage ) );
+            System.out.println( "      current BOB : 0x" + Long.toHexString( currentBtreeOfBtreesPage ) );
+            System.out.println( "      previous BOB : 0x" + Long.toHexString( previousBtreeOfBtreesPage ) );
+            System.out.println( "      current CopiedPages : 0x" + Long.toHexString( currentCopiedPagesBtreePage ) );
+            System.out.println( "      previous CopiedPages : 0x" + Long.toHexString( previousCopiedPagesBtreePage ) );
+
+            // Dump the Free pages list
+            dumpFreePages( firstFreePage );
+
+            // Dump the B-tree of B-trees
+            dumpBtreeHeader( currentBtreeOfBtreesPage );
+
+            // Dump the previous B-tree of B-trees if any
+            if ( previousBtreeOfBtreesPage != NO_PAGE )
+            {
+                dumpBtreeHeader( previousBtreeOfBtreesPage );
+            }
+
+            // Dump the CopiedPages B-tree
+            dumpBtreeHeader( currentCopiedPagesBtreePage );
+
+
+            // Dump the previous B-tree of B-trees if any
+            if ( previousCopiedPagesBtreePage != NO_PAGE )
+            {
+                dumpBtreeHeader( previousCopiedPagesBtreePage );
+            }
+
+            // Dump all the user's B-tree
+            randomFile.close();
+            System.out.println( "\\---------------------------- Dump ----------------------------/" );
+        }
+        catch ( IOException ioe )
+        {
+            System.out.println( "Exception while dumping the file : " + ioe.getMessage() );
+        }
+    }
+
+
+    /**
+     * Dump the free pages
+     */
+    private void dumpFreePages( long freePageOffset ) throws EndOfFileExceededException, IOException
+    {
+        System.out.println( "\n  FreePages : " );
+        int pageNb = 1;
+
+        while ( freePageOffset != NO_PAGE )
+        {
+            PageIO pageIo = fetchPage( freePageOffset );
+
+            System.out.println( "    freePage[" + pageNb + "] : 0x" + Long.toHexString( pageIo.getOffset() ) );
+
+            freePageOffset = pageIo.getNextPage();
+            pageNb++;
+        }
+    }
+
+
+    /**
+     * Dump a B-tree Header
+     */
+    private long dumpBtreeHeader( long btreeOffset ) throws EndOfFileExceededException, IOException
+    {
+        // First read the B-tree header
+        PageIO[] pageIos = readPageIOs( btreeOffset, Long.MAX_VALUE );
+
+        long dataPos = 0L;
+
+        // The B-tree current revision
+        long revision = readLong( pageIos, dataPos );
+        dataPos += LONG_SIZE;
+
+        // The nb elems in the tree
+        long nbElems = readLong( pageIos, dataPos );
+        dataPos += LONG_SIZE;
+
+        // The B-tree rootPage offset
+        long rootPageOffset = readLong( pageIos, dataPos );
+        dataPos += LONG_SIZE;
+
+        // The B-tree page size
+        int btreePageSize = readInt( pageIos, dataPos );
+        dataPos += INT_SIZE;
+
+        // The tree name
+        ByteBuffer btreeNameBytes = readBytes( pageIos, dataPos );
+        dataPos += INT_SIZE + btreeNameBytes.limit();
+        String btreeName = Strings.utf8ToString( btreeNameBytes );
+
+        // The keySerializer FQCN
+        ByteBuffer keySerializerBytes = readBytes( pageIos, dataPos );
+        dataPos += INT_SIZE + keySerializerBytes.limit();
+
+        String keySerializerFqcn = "";
+
+        if ( keySerializerBytes != null )
+        {
+            keySerializerFqcn = Strings.utf8ToString( keySerializerBytes );
         }
 
-        long position = HEADER_SIZE;
+        // The valueSerialier FQCN
+        ByteBuffer valueSerializerBytes = readBytes( pageIos, dataPos );
 
-        // Dump the BTrees
-        for ( int i = 0; i < nbBTree; i++ )
+        String valueSerializerFqcn = "";
+        dataPos += INT_SIZE + valueSerializerBytes.limit();
+
+        if ( valueSerializerBytes != null )
         {
-            LOG.debug( "  Btree[{}]", i );
-            PageIO[] pageIos = readPageIOs( position, Long.MAX_VALUE );
+            valueSerializerFqcn = Strings.utf8ToString( valueSerializerBytes );
+        }
+
+        // The B-tree allowDuplicates flag
+        int allowDuplicates = readInt( pageIos, dataPos );
+        boolean dupsAllowed = allowDuplicates != 0;
+
+        dataPos += INT_SIZE;
+
+//        System.out.println( "\n  B-Tree " + btreeName );
+//        System.out.println( "  ------------------------- " );
+
+//        System.out.println( "    nbPageIOs[" + pageIos.length + "] = " + pageIoList );
+        if ( LOG.isDebugEnabled() )
+        {
+            StringBuilder sb = new StringBuilder();
+            boolean isFirst = true;
 
             for ( PageIO pageIo : pageIos )
             {
-                LOG.debug( "    {}", pageIo );
+                if ( isFirst )
+                {
+                    isFirst = false;
+                }
+                else
+                {
+                    sb.append( ", " );
+                }
+
+                sb.append( "0x" ).append( Long.toHexString( pageIo.getOffset() ) );
             }
+
+            String pageIoList = sb.toString();
+
+            LOG.debug( "    PageIOs[{}] = {}", pageIos.length, pageIoList );
+
+//        System.out.println( "    dataSize = "+ pageIos[0].getSize() );
+            LOG.debug( "    dataSize = {}", pageIos[0].getSize() );
+
+            LOG.debug( "    B-tree '{}'", btreeName );
+            LOG.debug( "    revision : {}", revision );
+            LOG.debug( "    nbElems : {}", nbElems );
+            LOG.debug( "    rootPageOffset : 0x{}", Long.toHexString( rootPageOffset ) );
+            LOG.debug( "    B-tree page size : {}", btreePageSize );
+            LOG.debug( "    keySerializer : '{}'", keySerializerFqcn );
+            LOG.debug( "    valueSerializer : '{}'", valueSerializerFqcn );
+            LOG.debug( "    dups allowed : {}", dupsAllowed );
+//
+//        System.out.println( "    B-tree '" + btreeName + "'" );
+//        System.out.println( "    revision : " + revision );
+//        System.out.println( "    nbElems : " + nbElems );
+//        System.out.println( "    rootPageOffset : 0x" + Long.toHexString( rootPageOffset ) );
+//        System.out.println( "    B-tree page size : " + btreePageSize );
+//        System.out.println( "    keySerializer : " + keySerializerFqcn );
+//        System.out.println( "    valueSerializer : " + valueSerializerFqcn );
+//        System.out.println( "    dups allowed : " + dupsAllowed );
         }
 
-        randomFile.close();
+        return rootPageOffset;
     }
 
 
     /**
-     * Get the number of managed trees. We don't count the CopiedPage BTree. and the Revsion BTree
+     * Get the number of managed trees. We don't count the CopiedPage B-tree and the B-tree of B-trees
      *
-     * @return The number of managed BTrees
+     * @return The number of managed B-trees
      */
     public int getNbManagedTrees()
     {
-        return nbBtree - 2;
+        return nbBtree;
     }
 
 
     /**
-     * Get the managed trees. We don't return the CopiedPage BTree nor the Revision BTree.
+     * Get the managed B-trees. We don't return the CopiedPage B-tree nor the B-tree of B-trees.
      *
-     * @return The managed BTrees
+     * @return The managed B-trees
      */
     public Set<String> getManagedTrees()
     {
-        Set<String> btrees = new HashSet<String>( managedBTrees.keySet() );
-
-        btrees.remove( COPIED_PAGE_BTREE_NAME );
-        btrees.remove( REVISION_BTREE_NAME );
+        Set<String> btrees = new HashSet<String>( managedBtrees.keySet() );
 
         return btrees;
     }
 
 
     /**
-     * Store a reference to an old rootPage into the Revision BTree
+     * Stores the copied pages into the CopiedPages B-tree
      *
-     * @param btree The BTree we want to keep an old RootPage for
+     * @param name The B-tree name
+     * @param revision The revision
+     * @param copiedPages The pages that have been copied while creating this revision
+     * @throws IOException If we weren't able to store the data on disk
+     */
+    /* No Qualifier */ void storeCopiedPages( String name, long revision, long[] copiedPages ) throws IOException
+    {
+        RevisionName revisionName = new RevisionName( revision, name );
+
+        copiedPageBtree.insert( revisionName, copiedPages );
+    }
+
+
+    /**
+     * Store a reference to an old rootPage into the Revision B-tree
+     *
+     * @param btree The B-tree we want to keep an old RootPage for
      * @param rootPage The old rootPage
      * @throws IOException If we have an issue while writing on disk
      */
@@ -2370,30 +3343,30 @@
             return;
         }
 
-        if ( ( btree == copiedPageBTree ) || ( btree == revisionBTree ) )
+        if ( btree == copiedPageBtree )
         {
             return;
         }
 
-        RevisionName revisionName = new RevisionName( rootPage.getRevision(), btree.getName() );
+        NameRevision nameRevision = new NameRevision( btree.getName(), rootPage.getRevision() );
 
-        ( ( AbstractBTree<RevisionName, Long> ) revisionBTree ).insert( revisionName,
+        ( ( AbstractBTree<NameRevision, Long> ) btreeOfBtrees ).insert( nameRevision,
             ( ( AbstractPage<K, V> ) rootPage ).getOffset(), 0 );
 
         if ( LOG_CHECK.isDebugEnabled() )
         {
-            check();
+            MavibotInspector.check( this );
         }
     }
 
 
     /**
-     * Fetch the rootPage of a given BTree for a given revision.
+     * Fetch the rootPage of a given B-tree for a given revision.
      *
-     * @param btree The BTree we are interested in
+     * @param btree The B-tree we are interested in
      * @param revision The revision we want to get back
-     * @return The rootPage for this BTree and this revision, if any
-     * @throws KeyNotFoundException If we can't find the rootPage for this revision and this BTree
+     * @return The rootPage for this B-tree and this revision, if any
+     * @throws KeyNotFoundException If we can't find the rootPage for this revision and this B-tree
      * @throws IOException If we had an ise while accessing the data on disk
      */
     /* No qualifier */<K, V> Page<K, V> getRootPage( BTree<K, V> btree, long revision ) throws KeyNotFoundException,
@@ -2405,12 +3378,33 @@
             return btree.getRootPage();
         }
 
-        RevisionName revisionName = new RevisionName( revision, btree.getName() );
-        long rootPageOffset = revisionBTree.get( revisionName );
+        // Get the B-tree header offset
+        NameRevision nameRevision = new NameRevision( btree.getName(), revision );
+        long btreeHeaderOffset = btreeOfBtrees.get( nameRevision );
+
+        // get the B-tree rootPage
+        Page<K, V> btreeRoot = readRootPage( btree, btreeHeaderOffset );
+
+        return btreeRoot;
+    }
+
+
+    /**
+     * Read a root page from the B-tree header offset
+     */
+    private <K, V> Page<K, V> readRootPage( BTree<K, V> btree, long btreeHeaderOffset ) throws EndOfFileExceededException, IOException
+    {
+        // Read the B-tree header pages on disk
+        PageIO[] btreeHeaderPageIos = readPageIOs( btreeHeaderOffset, Long.MAX_VALUE );
+        long dataPos = LONG_SIZE + LONG_SIZE;
+
+        // The B-tree rootPage offset
+        long rootPageOffset = readLong( btreeHeaderPageIos, dataPos );
 
         // Read the rootPage pages on disk
         PageIO[] rootPageIos = readPageIOs( rootPageOffset, Long.MAX_VALUE );
 
+        // Now, convert it to a Page
         Page<K, V> btreeRoot = readPage( btree, rootPageIos );
 
         return btreeRoot;
@@ -2420,34 +3414,30 @@
     /**
      * Get one managed trees, knowing its name.
      *
-     * @return The managed BTrees
+     * @param name The B-tree name we are looking for
+     * @return The managed B-trees
      */
     public <K, V> BTree<K, V> getManagedTree( String name )
     {
-        return ( BTree<K, V> ) managedBTrees.get( name );
+        return ( BTree<K, V> ) managedBtrees.get( name );
     }
 
 
     /**
-     * Move a list of pages to the free page list. A logical page is associated with on
-     * or physical PageIO, which are on the disk. We have to move all those PagIO instance
+     * Move a list of pages to the free page list. A logical page is associated with one
+     * or more physical PageIOs, which are on the disk. We have to move all those PagIO instances
      * to the free list, and do the same in memory (we try to keep a reference to a set of
      * free pages.
      *
-     * @param btree The BTree which were owning the pages
+     * @param btree The B-tree which were owning the pages
+     * @param revision The current revision
      * @param pages The pages to free
-     * @throws IOException
-     * @throws EndOfFileExceededException
+     * @throws IOException If we had a problem while updating the file
+     * @throws EndOfFileExceededException If we tried to write after the end of the file
      */
-    /* Package protected */<K, V> void addFreePages( BTree<K, V> btree, List<Page<K, V>> pages )
-        throws EndOfFileExceededException,
-        IOException
+    /* Package protected */<K, V> void freePages( BTree<K, V> btree, long revision, List<Page<K, V>> pages )
+        throws EndOfFileExceededException, IOException
     {
-        if ( ( btree == copiedPageBTree ) || ( btree == revisionBTree ) )
-        {
-            return;
-        }
-
         if ( ( pages == null ) || pages.isEmpty() )
         {
             return;
@@ -2455,111 +3445,104 @@
 
         if ( !keepRevisions )
         {
-            // if the btree doesn't keep revisions, we can safely move
-            // the pages to the free page list.
-            // NOTE : potential improvement : we can update the header only when
-            // we have processed all the logical pages.
+            // if the B-tree doesn't keep revisions, we can safely move
+            // the pages to the freed page list.
+            if ( LOG.isDebugEnabled() )
+            {
+                LOG.debug( "Freeing the following pages :" );
+
+                for ( Page<K, V> page : pages )
+                {
+                    LOG.debug(  "    {}", page );
+                }
+            }
 
             for ( Page<K, V> page : pages )
             {
-                // Retrieve all the PageIO associated with this logical page
-                long firstOffset = ( ( AbstractPage<K, V> ) page ).getOffset();
+                long pageOffset = ((AbstractPage<K, V>)page).getOffset();
 
-                // skip the page with offset 0, this is the first in-memory root page that
-                // was copied during first insert in a BTree.
-                // a Node or Leaf will *never* have 0 or -1 as its offset
-                if ( firstOffset == NO_PAGE )
+                PageIO[] pageIos = readPageIOs( pageOffset, Long.MAX_VALUE );
+
+                for ( PageIO pageIo : pageIos )
                 {
-                    continue;
-                }
-
-                long lastOffset = ( ( AbstractPage<K, V> ) page ).getLastOffset();
-
-                // Update the pointers
-                if ( firstFreePage == NO_PAGE )
-                {
-                    // We don't have yet any free pageIos. The
-                    // PageIOs for this Page will be used
-                    firstFreePage = firstOffset;
-                }
-                else
-                {
-                    // We add the Page's PageIOs before the
-                    // existing free pages.
-                    long offset = ( ( AbstractPage<K, V> ) page ).getLastOffset();
-
-                    if ( offset == NO_PAGE )
-                    {
-                        offset = ( ( AbstractPage<K, V> ) page ).getOffset();
-                    }
-
-                    // Fetch the pageIO
-                    PageIO pageIo = fetchPage( offset );
-
-                    // Link it to the first free page
-                    pageIo.setNextPage( firstFreePage );
-
-                    LOG.debug( "Flushing the first free page" );
-
-                    // And flush it to disk
-                    flushPages( pageIo );
-
-                    // We can update the firstFreePage offset
-                    firstFreePage = firstOffset;
+                    freedPages.add( pageIo );
                 }
             }
         }
         else
         {
-            LOG.debug( "We should not get there" );
-
-            for ( Page<K, V> p : pages )
+            // We are keeping revisions of standard B-trees, so we move the pages to the CopiedPages B-tree
+            // but only for non managed B-trees
+            if ( LOG.isDebugEnabled() )
             {
-                addFreePage( btree, p );
+                LOG.debug( "Moving the following pages to the CopiedBtree :" );
+
+                for ( Page<K, V> page : pages )
+                {
+                    LOG.debug(  "    {}", page );
+                }
             }
-        }
-    }
 
+            long[] pageOffsets = new long[pages.size()];
+            int pos = 0;
 
-    /**
-     *
-     * TODO addFreePage.
-     *
-     * @param btree
-     * @param freePage
-     */
-    private <K, V> void addFreePage( BTree<K, V> btree, Page<K, V> freePage )
-    {
-        try
-        {
-            RevisionName revision = new RevisionName( freePage.getRevision(), btree.getName() );
-            long[] offsetArray = null;
-
-            if ( copiedPageBTree.hasKey( revision ) )
+            for ( Page<K, V> page : pages )
             {
-                offsetArray = copiedPageBTree.get( revision );
-                long[] tmp = new long[offsetArray.length + 1];
-                System.arraycopy( offsetArray, 0, tmp, 0, offsetArray.length );
-                offsetArray = tmp;
+                pageOffsets[pos++] = ((AbstractPage<K, V>)page).offset;
+            }
+
+            if ( ( btree.getType() != BTreeTypeEnum.BTREE_OF_BTREES ) && ( btree.getType() != BTreeTypeEnum.COPIED_PAGES_BTREE ) )
+            {
+                // Deal with standard B-trees
+                RevisionName revisionName = new RevisionName( revision, btree.getName() );
+
+                copiedPageBtree.insert( revisionName, pageOffsets );
+
+                // Update the RecordManager Copiedpage Offset
+                currentCopiedPagesBtreeOffset = ((PersistedBTree<RevisionName, long[]>)copiedPageBtree).getBtreeOffset();
             }
             else
             {
-                offsetArray = new long[1];
+                // Managed B-trees : we simply free the copied pages
+                for ( long pageOffset : pageOffsets )
+                {
+                    PageIO[] pageIos = readPageIOs( pageOffset, Long.MAX_VALUE );
+
+                    for ( PageIO pageIo : pageIos )
+                    {
+                        freedPages.add( pageIo );
+                    }
+                }
             }
-
-            offsetArray[offsetArray.length - 1] = ( ( AbstractPage<K, V> ) freePage ).getOffset();
-
-            ( ( AbstractBTree<RevisionName, long[]> ) copiedPageBTree ).insert( revision, offsetArray, 0 );
-        }
-        catch ( Exception e )
-        {
-            throw new FreePageException( e );
         }
     }
 
 
     /**
-     * @return the keepRevisions
+     * Add a PageIO to the list of free PageIOs
+     *
+     * @param pageIo The page to free
+     * @throws IOException If we weren't capable of updating the file
+     */
+    private void free( PageIO pageIo ) throws IOException
+    {
+        // We add the Page's PageIOs before the
+        // existing free pages.
+        // Link it to the first free page
+        pageIo.setNextPage( firstFreePage );
+
+        LOG.debug( "Flushing the first free page" );
+
+        // And flush it to disk
+        flushPages( pageIo );
+
+        // We can update the firstFreePage offset
+        firstFreePage = pageIo.getOffset();
+    }
+
+
+    /**
+     * @return the keepRevisions flag
      */
     public boolean isKeepRevisions()
     {
@@ -2568,7 +3551,7 @@
 
 
     /**
-     * @param keepRevisions the keepRevisions to set
+     * @param keepRevisions the keepRevisions flag to set
      */
     public void setKeepRevisions( boolean keepRevisions )
     {
@@ -2577,20 +3560,20 @@
 
 
     /**
-     * Creates a BTree and automatically adds it to the list of managed btrees
+     * Creates a B-tree and automatically adds it to the list of managed btrees
      *
-     * @param name the name of the BTree
+     * @param name the name of the B-tree
      * @param keySerializer key serializer
      * @param valueSerializer value serializer
      * @param allowDuplicates flag for allowing duplicate keys
-     * @return a managed BTree
-     * @throws IOException
-     * @throws BTreeAlreadyManagedException
+     * @return a managed B-tree
+     * @throws IOException If we weren't able to update the file on disk
+     * @throws BTreeAlreadyManagedException If the B-tree is already managed
      */
     @SuppressWarnings("all")
     public <K, V> BTree<K, V> addBTree( String name, ElementSerializer<K> keySerializer,
-        ElementSerializer<V> valueSerializer,
-        boolean allowDuplicates ) throws IOException, BTreeAlreadyManagedException
+        ElementSerializer<V> valueSerializer, boolean allowDuplicates )
+            throws IOException, BTreeAlreadyManagedException
     {
         PersistedBTreeConfiguration config = new PersistedBTreeConfiguration();
 
@@ -2604,459 +3587,109 @@
 
         if ( LOG_CHECK.isDebugEnabled() )
         {
-            check();
+            MavibotInspector.check( this );
         }
 
         return btree;
     }
 
-
-    private void setCheckedPage( long[] checkedPages, long offset, int pageSize )
-    {
-        long pageOffset = ( offset - HEADER_SIZE ) / pageSize;
-        int index = ( int ) ( pageOffset / 64L );
-        long mask = ( 1L << ( pageOffset % 64L ) );
-        long bits = checkedPages[index];
-
-        if ( ( bits & mask ) == 1 )
-        {
-            throw new RecordManagerException( "The page at : " + offset + " has already been checked" );
-        }
-
-        checkedPages[index] |= mask;
-
-    }
-
-
+    
     /**
-     * Check the free pages
-     *
-     * @param checkedPages
-     * @throws IOException
+     * Add a newly closd transaction into the closed transaction queue
      */
-    private void checkFreePages( long[] checkedPages, int pageSize, long firstFreePage )
-        throws IOException
+    /* no qualifier */ <K, V> void releaseTransaction( ReadTransaction<K, V> readTransaction )
     {
-        if ( firstFreePage == NO_PAGE )
-        {
-            return;
-        }
-
-        // Now, read all the free pages
-        long currentOffset = firstFreePage;
-        long fileSize = fileChannel.size();
-
-        while ( currentOffset != NO_PAGE )
-        {
-            if ( currentOffset > fileSize )
-            {
-                throw new FreePageException( "Wrong free page offset, above file size : " + currentOffset );
-            }
-
-            try
-            {
-                PageIO pageIo = fetchPage( currentOffset );
-
-                if ( currentOffset != pageIo.getOffset() )
-                {
-                    throw new InvalidBTreeException( "PageIO offset is incorrect : " + currentOffset + "-"
-                        + pageIo.getOffset() );
-                }
-
-                setCheckedPage( checkedPages, currentOffset, pageSize );
-
-                long newOffset = pageIo.getNextPage();
-                currentOffset = newOffset;
-            }
-            catch ( IOException ioe )
-            {
-                throw new InvalidBTreeException( "Cannot fetch page at : " + currentOffset );
-            }
-        }
+        RevisionName revisionName = new RevisionName( 
+            readTransaction.getRevision(), 
+            readTransaction.getBtreeHeader().getBtree().getName() );
+        //closedTransactionsQueue.add( revisionName );
     }
-
-
+    
+    
     /**
-     * Check the root page for a given BTree
-     * @throws IOException
-     * @throws EndOfFileExceededException
+     * Get the current BTreeHeader for a given Btree. It might not exist
      */
-    private void checkRoot( long[] checkedPages, long offset, int pageSize, long nbBTreeElems,
-        ElementSerializer keySerializer, ElementSerializer valueSerializer, boolean allowDuplicates )
-        throws EndOfFileExceededException, IOException
+    public BTreeHeader getBTreeHeader( String name )
     {
-        // Read the rootPage pages on disk
-        PageIO[] rootPageIos = readPageIOs( offset, Long.MAX_VALUE );
+        // Get a lock
+        btreeHeadersLock.readLock().lock();
+        
+        // get the current BTree Header for this BTree and revision
+        BTreeHeader<?, ?> btreeHeader = currentBTreeHeaders.get( name );
+        
+        // And unlock 
+        btreeHeadersLock.readLock().unlock();
 
-        // Deserialize the rootPage now
-        long position = 0L;
-
-        // The revision
-        long revision = readLong( rootPageIos, position );
-        position += LONG_SIZE;
-
-        // The number of elements in the page
-        int nbElems = readInt( rootPageIos, position );
-        position += INT_SIZE;
-
-        // The size of the data containing the keys and values
-        ByteBuffer byteBuffer = null;
-
-        // Reads the bytes containing all the keys and values, if we have some
-        ByteBuffer data = readBytes( rootPageIos, position );
-
-        if ( nbElems >= 0 )
-        {
-            // Its a leaf
-
-            // Check the page offset
-            long pageOffset = rootPageIos[0].getOffset();
-
-            if ( ( pageOffset < 0 ) || ( pageOffset > fileChannel.size() ) )
-            {
-                throw new InvalidBTreeException( "The page offset is incorrect : " + pageOffset );
-            }
-
-            // Check the page last offset
-            long pageLastOffset = rootPageIos[rootPageIos.length - 1].getOffset();
-
-            if ( ( pageLastOffset <= 0 ) || ( pageLastOffset > fileChannel.size() ) )
-            {
-                throw new InvalidBTreeException( "The page last offset is incorrect : " + pageLastOffset );
-            }
-
-            // Read each value and key
-            for ( int i = 0; i < nbElems; i++ )
-            {
-                // Just deserialize all the keys and values
-                if ( allowDuplicates )
-                {
-                    /*
-                    long value = OFFSET_SERIALIZER.deserialize( byteBuffer );
-
-                    rootPageIos = readPageIOs( value, Long.MAX_VALUE );
-
-                    BTree dupValueContainer = BTreeFactory.createBTree();
-                    dupValueContainer.setBtreeOffset( value );
-
-                    try
-                    {
-                        loadBTree( pageIos, dupValueContainer );
-                    }
-                    catch ( Exception e )
-                    {
-                        // should not happen
-                        throw new InvalidBTreeException( e );
-                    }
-                    */
-                }
-                else
-                {
-                    valueSerializer.deserialize( byteBuffer );
-                }
-
-                keySerializer.deserialize( byteBuffer );
-            }
-        }
-        else
-        {
-            /*
-            // It's a node
-            int nodeNbElems = -nbElems;
-
-            // Read each value and key
-            for ( int i = 0; i < nodeNbElems; i++ )
-            {
-                // This is an Offset
-                long offset = OFFSET_SERIALIZER.deserialize( byteBuffer );
-                long lastOffset = OFFSET_SERIALIZER.deserialize( byteBuffer );
-
-                ElementHolder valueHolder = new ReferenceHolder( btree, null, offset, lastOffset );
-                ( ( Node ) page ).setValue( i, valueHolder );
-
-                Object key = btree.getKeySerializer().deserialize( byteBuffer );
-                BTreeFactory.setKey( page, i, key );
-            }
-
-            // and read the last value, as it's a node
-            long offset = OFFSET_SERIALIZER.deserialize( byteBuffer );
-            long lastOffset = OFFSET_SERIALIZER.deserialize( byteBuffer );
-
-            ElementHolder valueHolder = new ReferenceHolder( btree, null, offset, lastOffset );
-            ( ( Node ) page ).setValue( nodeNbElems, valueHolder );*/
-        }
+        return btreeHeader;
     }
-
-
+    
+    
     /**
-     * Check a BTree
-     * @throws IllegalAccessException
-     * @throws InstantiationException
-     * @throws ClassNotFoundException
+     * {@inheritDoc}
      */
-    private long checkBTree( long[] checkedPages, PageIO[] pageIos, int pageSize, boolean isLast )
-        throws EndOfFileExceededException, IOException, InstantiationException, IllegalAccessException,
-        ClassNotFoundException
+    public void updateNewBTreeHeaders( BTreeHeader btreeHeader )
     {
-        long dataPos = 0L;
-
-        // The BTree current revision
-        long revision = readLong( pageIos, dataPos );
-        dataPos += LONG_SIZE;
-
-        // The nb elems in the tree
-        long nbElems = readLong( pageIos, dataPos );
-        dataPos += LONG_SIZE;
-
-        // The BTree rootPage offset
-        long rootPageOffset = readLong( pageIos, dataPos );
-
-        if ( ( rootPageOffset < 0 ) || ( rootPageOffset > fileChannel.size() ) )
-        {
-            throw new InvalidBTreeException( "The rootpage is incorrect : " + rootPageOffset );
-        }
-
-        dataPos += LONG_SIZE;
-
-        // The next BTree offset
-        long nextBTreeOffset = readLong( pageIos, dataPos );
-
-        if ( ( ( rootPageOffset < 0 ) && ( !isLast ) ) || ( nextBTreeOffset > fileChannel.size() ) )
-        {
-            throw new InvalidBTreeException( "The rootpage is incorrect : " + rootPageOffset );
-        }
-
-        dataPos += LONG_SIZE;
-
-        // The BTree page size
-        int btreePageSize = readInt( pageIos, dataPos );
-
-        if ( ( btreePageSize < 2 ) || ( ( btreePageSize & ( ~btreePageSize + 1 ) ) != btreePageSize ) )
-        {
-            throw new InvalidBTreeException( "The BTree page size is not a power of 2 : " + btreePageSize );
-        }
-
-        dataPos += INT_SIZE;
-
-        // The tree name
-        ByteBuffer btreeNameBytes = readBytes( pageIos, dataPos );
-        dataPos += INT_SIZE;
-
-        dataPos += btreeNameBytes.limit();
-        String btreeName = Strings.utf8ToString( btreeNameBytes );
-
-        // The keySerializer FQCN
-        ByteBuffer keySerializerBytes = readBytes( pageIos, dataPos );
-
-        String keySerializerFqcn = null;
-        dataPos += INT_SIZE;
-
-        if ( keySerializerBytes != null )
-        {
-            dataPos += keySerializerBytes.limit();
-            keySerializerFqcn = Strings.utf8ToString( keySerializerBytes );
-        }
-        else
-        {
-            keySerializerFqcn = "";
-        }
-
-        // The valueSerialier FQCN
-        ByteBuffer valueSerializerBytes = readBytes( pageIos, dataPos );
-
-        String valueSerializerFqcn = null;
-        dataPos += INT_SIZE;
-
-        if ( valueSerializerBytes != null )
-        {
-            dataPos += valueSerializerBytes.limit();
-            valueSerializerFqcn = Strings.utf8ToString( valueSerializerBytes );
-        }
-        else
-        {
-            valueSerializerFqcn = "";
-        }
-
-        // The BTree allowDuplicates flag
-        int allowDuplicates = readInt( pageIos, dataPos );
-        dataPos += INT_SIZE;
-
-        // Now, check the rootPage, which can be a Leaf or a Node, depending
-        // on the number of elements in the tree : if it's above the pageSize,
-        // it's a Node, otherwise it's a Leaf
-        Class<?> valueSerializer = Class.forName( valueSerializerFqcn );
-        Class<?> keySerializer = Class.forName( keySerializerFqcn );
-
-        /*
-        checkRoot( checkedPages, rootPageOffset, pageSize, nbElems,
-            ( ElementSerializer<?> ) keySerializer.newInstance(),
-            ( ElementSerializer<?> ) valueSerializer.newInstance(), allowDuplicates != 0 );
-        */
-
-        return nextBTreeOffset;
+        newBTreeHeaders.put( btreeHeader.getBtree().getName(), btreeHeader );
     }
-
-
+    
+    
     /**
-     * Check each BTree we manage
-     * @throws IOException
-     * @throws EndOfFileExceededException
-     * @throws ClassNotFoundException
-     * @throws IllegalAccessException
-     * @throws InstantiationException
+     * Swap the current BtreeHeader map with the new one. This method will only
+     * be called in a single trhead, when the current transaction will be committed.
      */
-    private void checkBTrees( long[] checkedPages, int pageSize, int nbBTrees ) throws EndOfFileExceededException,
-        IOException, InstantiationException, IllegalAccessException, ClassNotFoundException
+    private void swapCurrentBtreeHeaders()
     {
-        // Iterate on each BTree until we have exhausted all of them. The number
-        // of btrees is just used to check that we have the correct number
-        // of stored BTrees, as they are all linked.
-        long position = HEADER_SIZE;
+        // Copy the reference to the current BtreeHeader Map
+        Map<String, BTreeHeader<?, ?>> tmp = currentBTreeHeaders;
+        
+        // Get a write lock
+        btreeHeadersLock.writeLock().lock();
 
-        for ( int i = 0; i < nbBTrees; i++ )
-        {
-            // Load the pageIOs containing the BTree
-            PageIO[] pageIos = readPageIOs( position, Long.MAX_VALUE );
+        // Swap the new BTreeHeader Map
+        currentBTreeHeaders = newBTreeHeaders;
+        
+        // And unlock 
+        btreeHeadersLock.writeLock().unlock();
 
-            // Check that they are correctly linked and not already used
-            int pageNb = 0;
+        // Last, not least, clear the Map and reinject the latest revision in it
+        tmp.clear();
+        tmp.putAll( currentBTreeHeaders );
 
-            for ( PageIO currentPageIo : pageIos )
-            {
-                //
-                long nextPageOffset = currentPageIo.getNextPage();
-
-                if ( pageNb == pageIos.length - 1 )
-                {
-                    if ( nextPageOffset != NO_PAGE )
-                    {
-                        throw new InvalidBTreeException( "The pointer to the next page is not valid, expected NO_PAGE" );
-                    }
-                }
-                else
-                {
-                    if ( nextPageOffset == NO_PAGE )
-                    {
-                        throw new InvalidBTreeException( "The pointer to the next page is not valid, NO_PAGE" );
-                    }
-                }
-
-                if ( ( nextPageOffset != NO_PAGE ) && ( ( nextPageOffset - HEADER_SIZE ) % pageSize != 0 ) )
-                {
-                    throw new InvalidBTreeException( "The pointer to the next page is not valid" );
-                }
-
-                // Update the array of processed pages
-                setCheckedPage( checkedPages, currentPageIo.getOffset(), pageSize );
-            }
-
-            // Now check the BTree
-            long nextBTree = checkBTree( checkedPages, pageIos, pageSize, i == nbBTrees - 1 );
-
-            if ( ( nextBTree == NO_PAGE ) && ( i < nbBTrees - 1 ) )
-            {
-                throw new InvalidBTreeException( "The pointer to the next BTree is incorrect" );
-            }
-
-            position = nextBTree;
-        }
+        // And update the new BTreeHeader map
+        newBTreeHeaders = tmp;
     }
-
-
+    
+    
     /**
-     * Check the whole file
+     * revert the new BTreeHeaders Map to the current BTreeHeader Map. This method
+     * is called when we have to rollback a transaction.
      */
-    private void check()
+    private void revertBtreeHeaders()
     {
-        try
-        {
-            // First check the header
-            ByteBuffer header = ByteBuffer.allocate( HEADER_SIZE );
-            long fileSize = fileChannel.size();
-
-            if ( fileSize < HEADER_SIZE )
-            {
-                throw new InvalidBTreeException( "File size too small : " + fileSize );
-            }
-
-            // Read the header
-            fileChannel.read( header, 0L );
-            header.flip();
-
-            // The page size. It must be a power of 2, and above 16.
-            int pageSize = header.getInt();
-
-            if ( ( pageSize < 0 ) || ( pageSize < 32 ) || ( ( pageSize & ( ~pageSize + 1 ) ) != pageSize ) )
-            {
-                throw new InvalidBTreeException( "Wrong page size : " + pageSize );
-            }
-
-            // Compute the number of pages in this file
-            long nbPages = ( fileSize - HEADER_SIZE ) / pageSize;
-
-            // The number of trees. It must be at least 2 and > 0
-            int nbBTrees = header.getInt();
-
-            if ( nbBTrees < 0 )
-            {
-                throw new InvalidBTreeException( "Wrong nb trees : " + nbBTrees );
-            }
-
-            // The first free page offset. It must be either -1 or below file size
-            // and its value must be a modulo of pageSize
-            long firstFreePage = header.getLong();
-
-            if ( firstFreePage > fileSize )
-            {
-                throw new InvalidBTreeException( "First free page pointing after the end of the file : "
-                    + firstFreePage );
-            }
-
-            if ( ( firstFreePage != NO_PAGE ) && ( ( ( firstFreePage - HEADER_SIZE ) % pageSize ) != 0 ) )
-            {
-                throw new InvalidBTreeException( "First free page not pointing to a correct offset : " + firstFreePage );
-            }
-
-            int nbPageBits = ( int ) ( nbPages / 64 );
-
-            // Create an array of pages to be checked
-            // We use one bit per page. It's 0 when the page
-            // hasn't been checked, 1 otherwise.
-            long[] checkedPages = new long[nbPageBits + 1];
-
-            // Then the free files
-            checkFreePages( checkedPages, pageSize, firstFreePage );
-
-            // The BTrees
-            checkBTrees( checkedPages, pageSize, nbBTrees );
-        }
-        catch ( Exception e )
-        {
-            // We catch the exception and rethrow it immediately to be able to
-            // put a breakpoint here
-            e.printStackTrace();
-            throw new InvalidBTreeException( "Error : " + e.getMessage() );
-        }
+        // Clean up teh new BTreeHeaders Map
+        newBTreeHeaders.clear();
+        
+        // Reinject the latest revision in it
+        newBTreeHeaders.putAll( currentBTreeHeaders );
     }
 
-
+    
     /**
-     * Loads a BTree holding the values of a duplicate key
+     * Loads a B-tree holding the values of a duplicate key
      * This tree is also called as dups tree or sub tree
      *
-     * @param offset the offset of the BTree header
-     * @return the deserialized BTree
+     * @param offset the offset of the B-tree header
+     * @return the deserialized B-tree
      */
-    /* No qualifier */<K, V> BTree<K, V> loadDupsBTree( long offset )
+    /* No qualifier */<K, V> BTree<V, V> loadDupsBtree( long btreeHeaderOffset, BTree<K, V> parentBtree )
     {
         try
         {
-            PageIO[] pageIos = readPageIOs( offset, Long.MAX_VALUE );
+            PageIO[] pageIos = readPageIOs( btreeHeaderOffset, Long.MAX_VALUE );
 
-            BTree<K, V> subBtree = BTreeFactory.createPersistedBTree();
-            ( ( PersistedBTree<K, V> ) subBtree ).setBtreeOffset( offset );
-
-            loadBTree( pageIos, subBtree );
+            BTree<V, V> subBtree = BTreeFactory.<V, V> createPersistedBTree( BTreeTypeEnum.PERSISTED_SUB );
+            loadBtree( pageIos, subBtree, parentBtree );
+            
 
             return subBtree;
         }
@@ -3069,15 +3702,6 @@
 
 
     /**
-     * @return the pendingPages
-     */
-    /* no qualifier*/ <K, V> Map<Page<?, ?>, BTree<?, ?>> getPendingPages()
-    {
-        return pendingPages;
-    }
-
-
-    /**
      * @see Object#toString()
      */
     public String toString()
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/RevisionNameComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/RevisionNameComparator.java
index c0aebef..1d3e62d 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/RevisionNameComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/RevisionNameComparator.java
@@ -30,6 +30,17 @@
  */
 /* no qualifier*/class RevisionNameComparator implements Comparator<RevisionName>
 {
+    /** A static instance of a RevisionNameComparator */
+    public static final RevisionNameComparator INSTANCE = new RevisionNameComparator();
+
+    /**
+     * A private constructor of the RevisionNameComparator class
+     */
+    private RevisionNameComparator()
+    {
+    }
+
+
     /**
      * {@inheritDoc}
      */
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/RevisionNameSerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/RevisionNameSerializer.java
index f64a419..b5920e3 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/RevisionNameSerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/RevisionNameSerializer.java
@@ -41,12 +41,15 @@
  */
 /* no qualifier*/class RevisionNameSerializer extends AbstractElementSerializer<RevisionName>
 {
+    /** A static instance of a RevisionNameSerializer */
+    /*No qualifier*/ final static RevisionNameSerializer INSTANCE = new RevisionNameSerializer();
+
     /**
      * Create a new instance of a RevisionNameSerializer
      */
-    /* no qualifier*/RevisionNameSerializer()
+    private RevisionNameSerializer()
     {
-        super( new RevisionNameComparator() );
+        super( RevisionNameComparator.INSTANCE );
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/TransactionManager.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/TransactionManager.java
new file mode 100644
index 0000000..aa458e7
--- /dev/null
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/TransactionManager.java
@@ -0,0 +1,63 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree;
+
+/**
+ * An interface used to manage the transactions mechanism in B-trees. Transactions are cross
+ * B-trees.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface TransactionManager
+{
+    /**
+     * Starts a transaction
+     */
+    void beginTransaction();
+
+
+    /**
+     * Commits a transaction
+     */
+    void commit();
+
+
+    /**
+     * Rollback a transaction
+     */
+    void rollback();
+    
+    
+    /**
+     * Gets the current BtreeHeader for a given BTree.
+     * 
+     * @param btreeName The Btree name we are looking the BtreeHeader for
+     * @return the current BTreeHeader
+     */
+    BTreeHeader<?, ?> getBTreeHeader( String btreeName );
+    
+    
+    /**
+     * Updates the map of new BTreeHeaders
+     * 
+     * @param btreeHeader The new BtreeHeader
+     */
+    void updateNewBTreeHeaders( BTreeHeader<?, ?> btreeHeader );
+}
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/TupleCursor.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/TupleCursor.java
index 9462ee1..4650eb4 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/TupleCursor.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/TupleCursor.java
@@ -34,7 +34,7 @@
  *
  * @param <K> The type for the Key
  * @param <V> The type for the stored value
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class TupleCursor<K, V>
@@ -59,8 +59,16 @@
 
 
     /**
+     * Creates a new instance of Cursor.
+     */
+    protected TupleCursor()
+    {
+    }
+
+
+    /**
      * Creates a new instance of Cursor, starting on a page at a given position.
-     * 
+     *
      * @param transaction The transaction this operation is protected by
      * @param stack The stack of parent's from root to this page
      */
@@ -167,10 +175,10 @@
 
     /**
      * Tells if the cursor can return a next element
-     * 
+     *
      * @return true if there are some more elements
-     * @throws IOException 
-     * @throws EndOfFileExceededException 
+     * @throws IOException
+     * @throws EndOfFileExceededException
      */
     public boolean hasNext() throws EndOfFileExceededException, IOException
     {
@@ -207,7 +215,7 @@
                 return true;
             }
 
-            // Ok, here, we have reached the last value in the leaf. We have to go up and 
+            // Ok, here, we have reached the last value in the leaf. We have to go up and
             // see if we have some remaining values
             int currentDepth = depth - 1;
 
@@ -234,10 +242,10 @@
 
     /**
      * Find the next key/value
-     * 
+     *
      * @return A Tuple containing the found key and value
-     * @throws IOException 
-     * @throws EndOfFileExceededException 
+     * @throws IOException
+     * @throws EndOfFileExceededException
      */
     public Tuple<K, V> next() throws EndOfFileExceededException, IOException
     {
@@ -324,7 +332,7 @@
     /**
      * Get the next non-duplicate key.
      * If the BTree contains :
-     * 
+     *
      *  <ul>
      *    <li><1,0></li>
      *    <li><1,1></li>
@@ -332,9 +340,9 @@
      *    <li><2,0></li>
      *    <li><2,1></li>
      *  </ul>
-     *   
+     *
      *  and cursor is present at <1,1> then the returned tuple will be <2,0> (not <1,2>)
-     *  
+     *
      * @return A Tuple containing the found key and value
      * @throws EndOfFileExceededException
      * @throws IOException
@@ -402,10 +410,10 @@
 
     /**
      * Tells if the cursor can return a next key
-     * 
+     *
      * @return true if there are some more keys
-     * @throws IOException 
-     * @throws EndOfFileExceededException 
+     * @throws IOException
+     * @throws EndOfFileExceededException
      */
     public boolean hasNextKey() throws EndOfFileExceededException, IOException
     {
@@ -439,10 +447,10 @@
 
     /**
      * Tells if the cursor can return a previous element
-     * 
+     *
      * @return true if there are some more elements
-     * @throws IOException 
-     * @throws EndOfFileExceededException 
+     * @throws IOException
+     * @throws EndOfFileExceededException
      */
     public boolean hasPrev() throws EndOfFileExceededException, IOException
     {
@@ -480,7 +488,7 @@
                 return true;
             }
 
-            // Ok, here, we have reached the first value in the leaf. We have to go up and 
+            // Ok, here, we have reached the first value in the leaf. We have to go up and
             // see if we have some remaining values
             int currentDepth = depth - 1;
 
@@ -506,10 +514,10 @@
 
     /**
      * Find the previous key/value
-     * 
+     *
      * @return A Tuple containing the found key and value
-     * @throws IOException 
-     * @throws EndOfFileExceededException 
+     * @throws IOException
+     * @throws EndOfFileExceededException
      */
     public Tuple<K, V> prev() throws EndOfFileExceededException, IOException
     {
@@ -597,7 +605,7 @@
     /**
      * Get the previous non-duplicate key.
      * If the BTree contains :
-     * 
+     *
      *  <ul>
      *    <li><1,0></li>
      *    <li><1,1></li>
@@ -605,9 +613,9 @@
      *    <li><2,0></li>
      *    <li><2,1></li>
      *  </ul>
-     *   
+     *
      *  and cursor is present at <2,1> then the returned tuple will be <1,0> (not <2,0>)
-     *  
+     *
      * @return A Tuple containing the found key and value
      * @throws EndOfFileExceededException
      * @throws IOException
@@ -653,7 +661,7 @@
             }
         }
 
-        // Update the Tuple 
+        // Update the Tuple
         AbstractPage<K, V> leaf = ( AbstractPage<K, V> ) ( parentPos.page );
 
         // The key
@@ -671,10 +679,10 @@
 
     /**
      * Tells if the cursor can return a previous key
-     * 
+     *
      * @return true if there are some more keys
-     * @throws IOException 
-     * @throws EndOfFileExceededException 
+     * @throws IOException
+     * @throws EndOfFileExceededException
      */
     public boolean hasPrevKey() throws EndOfFileExceededException, IOException
     {
@@ -693,25 +701,30 @@
             return false;
         }
 
-        if ( parentPos.pos == 0 )
+        switch ( parentPos.pos )
         {
-            // Beginning of the leaf. We have to go back into the stack up to the
-            // parent, and down to the leaf
-            return hasPrevParentPos();
-        }
-        else
-        {
-            return true;
+            case 0 :
+                // Beginning of the leaf. We have to go back into the stack up to the
+                // parent, and down to the leaf
+                return hasPrevParentPos();
+                
+            case -1 :
+                // no previous key
+                return false;
+                
+            default :
+                // we have a previous key
+                return true;
         }
     }
 
 
     /**
      * Tells if there is a next ParentPos
-     * 
+     *
      * @return the new ParentPos instance, or null if we have no following leaf
-     * @throws IOException 
-     * @throws EndOfFileExceededException 
+     * @throws IOException
+     * @throws EndOfFileExceededException
      */
     private boolean hasNextParentPos() throws EndOfFileExceededException, IOException
     {
@@ -758,10 +771,10 @@
 
     /**
      * Find the leaf containing the following elements.
-     * 
+     *
      * @return the new ParentPos instance, or null if we have no following leaf
-     * @throws IOException 
-     * @throws EndOfFileExceededException 
+     * @throws IOException
+     * @throws EndOfFileExceededException
      */
     private ParentPos<K, V> findNextParentPos() throws EndOfFileExceededException, IOException
     {
@@ -818,10 +831,10 @@
 
     /**
      * Find the leaf containing the previous elements.
-     * 
+     *
      * @return the new ParentPos instance, or null if we have no previous leaf
-     * @throws IOException 
-     * @throws EndOfFileExceededException 
+     * @throws IOException
+     * @throws EndOfFileExceededException
      */
     private ParentPos<K, V> findPrevParentPos() throws EndOfFileExceededException, IOException
     {
@@ -880,10 +893,10 @@
 
     /**
      * Tells if there is a prev ParentPos
-     * 
+     *
      * @return the new ParentPos instance, or null if we have no previous leaf
-     * @throws IOException 
-     * @throws EndOfFileExceededException 
+     * @throws IOException
+     * @throws EndOfFileExceededException
      */
     private boolean hasPrevParentPos() throws EndOfFileExceededException, IOException
     {
@@ -949,7 +962,7 @@
 
     /**
      * Get the current revision
-     * 
+     *
      * @return The revision this cursor is based on
      */
     public long getRevision()
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/ValueBTreeCursor.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/ValueBTreeCursor.java
index f9ba802..ba1e0e6 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/ValueBTreeCursor.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/ValueBTreeCursor.java
@@ -23,6 +23,7 @@
 import java.io.IOException;
 
 import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.BTree;
 
 
@@ -60,6 +61,11 @@
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
+        catch ( KeyNotFoundException knfe )
+        {
+            // TODO Auto-generated catch block
+            knfe.printStackTrace();
+        }
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/WriteTransaction.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/WriteTransaction.java
index 752c3d0..b6f9b68 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/WriteTransaction.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/WriteTransaction.java
@@ -19,8 +19,6 @@
  */
 package org.apache.directory.mavibot.btree;
 
-import java.io.IOException;
-import java.util.Map;
 import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.directory.mavibot.btree.exception.BadTransactionStateException;
@@ -32,28 +30,29 @@
  */
 /* no qualifier */ class WriteTransaction
 {
-    /** The recordManager on which this transaction is applied */
-    private RecordManager recordManager;
-
     /** A lock used to protect the write operation against concurrent access */
     protected ReentrantLock writeLock;
 
-    /* no qualifier */WriteTransaction( RecordManager recordManager )
+    /* no qualifier */WriteTransaction()
     {
-        System.out.println( "Creating the transaction oject" );
-        this.recordManager = recordManager;
+        //System.out.println( "Creating the transaction oject" );
         writeLock = new ReentrantLock();
     }
 
 
     /* no qualifier */ void start()
     {
+        /*
         if ( writeLock.isLocked() )
         {
             throw new BadTransactionStateException( "Cannot start a write transaction when it's already started" );
         }
+        */
+
+        //System.out.println( "Start a TXN [" + Thread.currentThread().getName() + "]" );
 
         writeLock.lock();
+        //System.out.println( "WriteTransaction " + Thread.currentThread().getName() );
     }
 
 
@@ -64,37 +63,7 @@
             throw new BadTransactionStateException( "Cannot commit a write transaction when it's not started" );
         }
 
-        Map<?, ?> pendingPages = recordManager.getPendingPages();
-
-        for ( Object object : pendingPages.keySet() )
-        {
-            BTree btree = (BTree)pendingPages.get( object );
-
-            try
-            {
-                recordManager.writePage( btree, (Page)object, ((Page)object).getRevision() );
-            }
-            catch ( IOException e )
-            {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        }
-
-        /*
-        recordManager.updateRecordManagerHeader();
-
-        // Update the BTree header now
-        recordManager.updateBtreeHeader( btree, ( ( AbstractPage<K, V> ) rootPage ).getOffset() );
-
-        // Moved the free pages into the list of free pages
-        recordManager.addFreePages( this, result.getCopiedPages() );
-
-        // Store the created rootPage into the revision BTree, this will be stored in RecordManager only if revisions are set to keep
-        recordManager.storeRootPage( this, rootPage );
-        */
-
-        pendingPages.clear();
+        //System.out.println( "Commit a TXN[" + Thread.currentThread().getName() + "]" );
 
         writeLock.unlock();
     }
@@ -107,6 +76,7 @@
             throw new BadTransactionStateException( "Cannot commit a write transaction when it's not started" );
         }
 
+        //System.out.println( "Rollback a TXN" );
         writeLock.unlock();
     }
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/BooleanArrayComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/BooleanArrayComparator.java
index 2e044dd..7c052a5 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/BooleanArrayComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/BooleanArrayComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -26,14 +26,25 @@
 /**
  * Compares boolean arrays. A boolean is considered as below the other one if the first boolean
  * is false when the second one is true.
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class BooleanArrayComparator implements Comparator<boolean[]>
 {
+    /** A static instance of a BooleanArrayComparator */
+    public static final BooleanArrayComparator INSTANCE = new BooleanArrayComparator();
+
+    /**
+     * A private constructor of the BooleanArrayComparator class
+     */
+    private BooleanArrayComparator()
+    {
+    }
+
+
     /**
      * Compare two boolean arrays.
-     * 
+     *
      * @param booleanArray1 First boolean array
      * @param booleanArray2 Second boolean array
      * @return 1 if booleanArray1 > booleanArray2, 0 if booleanArray1 == booleanArray2, -1 if booleanArray1 < booleanArray2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/BooleanComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/BooleanComparator.java
index 4d29875..4ffbb88 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/BooleanComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/BooleanComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,25 @@
 
 /**
  * Compares booleans
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class BooleanComparator implements Comparator<Boolean>
 {
+    /** A static instance of a BooleanComparator */
+    public static final BooleanComparator INSTANCE = new BooleanComparator();
+
+    /**
+     * A private constructor of the BooleanComparator class
+     */
+    private BooleanComparator()
+    {
+    }
+
+
     /**
      * Compare two booleans.
-     * 
+     *
      * @param boolean1 First boolean
      * @param boolean2 Second boolean
      * @return 1 if boolean1 > boolean2, 0 if boolean1 == boolean2, -1 if boolean1 < boolean2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ByteArrayComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ByteArrayComparator.java
index 8fac153..0b74659 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ByteArrayComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ByteArrayComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,25 @@
 
 /**
  * Compares byte arrays.
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class ByteArrayComparator implements Comparator<byte[]>
 {
+    /** A static instance of a ByteArrayComparator */
+    public static final ByteArrayComparator INSTANCE = new ByteArrayComparator();
+
+    /**
+     * A private constructor of the ByteArrayComparator class
+     */
+    private ByteArrayComparator()
+    {
+    }
+
+
     /**
      * Compare two byte arrays.
-     * 
+     *
      * @param byteArray1 First byteArray
      * @param byteArray2 Second byteArray
      * @return 1 if byteArray1 > byteArray2, 0 if byteArray1 == byteArray2, -1 if byteArray1 < byteArray2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ByteComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ByteComparator.java
index 291517d..e6f673d 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ByteComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ByteComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,25 @@
 
 /**
  * Compares bytes
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class ByteComparator implements Comparator<Byte>
 {
+    /** A static instance of a ByteComparator */
+    public static final ByteComparator INSTANCE = new ByteComparator();
+
+    /**
+     * A private constructor of the ByteComparator class
+     */
+    private ByteComparator()
+    {
+    }
+
+
     /**
      * Compare two bytes.
-     * 
+     *
      * @param byte1 First byte
      * @param byte2 Second byte
      * @return 1 if byte1 > byte2, 0 if byte1 == byte2, -1 if byte1 < byte2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/CharArrayComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/CharArrayComparator.java
index ce79319..5f1a847 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/CharArrayComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/CharArrayComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,25 @@
 
 /**
  * Compares char arrays
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class CharArrayComparator implements Comparator<char[]>
 {
+    /** A static instance of a CharArrayComparator */
+    public static final CharArrayComparator INSTANCE = new CharArrayComparator();
+
+    /**
+     * A private constructor of the CharArrayComparator class
+     */
+    private CharArrayComparator()
+    {
+    }
+
+
     /**
      * Compare two char arrays.
-     * 
+     *
      * @param charArray1 First char array
      * @param charArray2 Second char array
      * @return 1 if charArray1 > charArray2, 0 if charArray1 == charArray2, -1 if charArray1 < charArray2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/CharComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/CharComparator.java
index ba3acfd..9c4302b 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/CharComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/CharComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,25 @@
 
 /**
  * Compares chars
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class CharComparator implements Comparator<Character>
 {
+    /** A static instance of a CharComparator */
+    public static final CharComparator INSTANCE = new CharComparator();
+
+    /**
+     * A private constructor of the CharComparator class
+     */
+    private CharComparator()
+    {
+    }
+
+
     /**
      * Compare two chars.
-     * 
+     *
      * @param char1 First char
      * @param char2 Second char
      * @return 1 if char1 > char2, 0 if char1 == char2, -1 if char1 < char2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/IntArrayComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/IntArrayComparator.java
index 39c9068..7253b97 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/IntArrayComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/IntArrayComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,25 @@
 
 /**
  * Compares int arrays
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class IntArrayComparator implements Comparator<int[]>
 {
+    /** A static instance of a IntArrayComparator */
+    public static final IntArrayComparator INSTANCE = new IntArrayComparator();
+
+    /**
+     * A private constructor of the IntArrayComparator class
+     */
+    private IntArrayComparator()
+    {
+    }
+
+
     /**
      * Compare two long arrays.
-     * 
+     *
      * @param intArray1 First int array
      * @param intArray2 Second int array
      * @return 1 if intArray1 > intArray2, 0 if intArray1 == intArray2, -1 if intArray1 < intArray2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/IntComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/IntComparator.java
index aece0cc..8c6b38a 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/IntComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/IntComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,25 @@
 
 /**
  * Compares integers
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class IntComparator implements Comparator<Integer>
 {
+    /** A static instance of a IntComparator */
+    public static final IntComparator INSTANCE = new IntComparator();
+
+    /**
+     * A private constructor of the IntComparator class
+     */
+    private IntComparator()
+    {
+    }
+
+
     /**
      * Compare two integers.
-     * 
+     *
      * @param integer1 First integer
      * @param integer2 Second integer
      * @return 1 if integer1 > integer2, 0 if integer1 == integer2, -1 if integer1 < integer2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/LongArrayComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/LongArrayComparator.java
index 80c54be..80f681c 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/LongArrayComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/LongArrayComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,25 @@
 
 /**
  * Compares long arrays
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class LongArrayComparator implements Comparator<long[]>
 {
+    /** A static instance of a LongArrayComparator */
+    public static final LongArrayComparator INSTANCE = new LongArrayComparator();
+
+    /**
+     * A private constructor of the LongArrayComparator class
+     */
+    private LongArrayComparator()
+    {
+    }
+
+
     /**
      * Compare two long arrays.
-     * 
+     *
      * @param longArray1 First long array
      * @param longArray2 Second long array
      * @return 1 if longArray1 > longArray2, 0 if longArray1 == longArray2, -1 if longArray1 < longArray2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/LongComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/LongComparator.java
index 22ceb3b..53bf82b 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/LongComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/LongComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,23 @@
 
 /**
  * Compares Longs
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class LongComparator implements Comparator<Long>
 {
+    /** A static instance of a LongComparator */
+    public static final LongComparator INSTANCE = new LongComparator();
+
+    /**
+     * A private constructor of the BooleanArrayComparator class
+     */
+    private LongComparator()
+    {
+    }
     /**
      * Compare two longs.
-     * 
+     *
      * @param long1 First long
      * @param long2 Second long
      * @return 1 if long1 > long2, 0 if long1 == long2, -1 if long1 < long2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ShortArrayComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ShortArrayComparator.java
index da500ad..dea7430 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ShortArrayComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ShortArrayComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,25 @@
 
 /**
  * Compares short arrays
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class ShortArrayComparator implements Comparator<short[]>
 {
+    /** A static instance of a ShortArrayComparator */
+    public static final ShortArrayComparator INSTANCE = new ShortArrayComparator();
+
+    /**
+     * A private constructor of the ShortArrayComparator class
+     */
+    private ShortArrayComparator()
+    {
+    }
+
+
     /**
      * Compare two short arrays.
-     * 
+     *
      * @param shortArray1 First short array
      * @param shortArray2 Second short array
      * @return 1 if shortArray1 > shortArray2, 0 if shortArray1 == shortArray2, -1 if shortArray1 < shortArray2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ShortComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ShortComparator.java
index 246782e..117209a 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ShortComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/ShortComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,25 @@
 
 /**
  * Compares shorts
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class ShortComparator implements Comparator<Short>
 {
+    /** A static instance of a ShortComparator */
+    public static final ShortComparator INSTANCE = new ShortComparator();
+
+    /**
+     * A private constructor of the ShortComparator class
+     */
+    private ShortComparator()
+    {
+    }
+
+
     /**
      * Compare two shorts.
-     * 
+     *
      * @param short1 First short
      * @param short2 Second short
      * @return 1 if short1 > short2, 0 if short1 == short2, -1 if short1 < short2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/StringComparator.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/StringComparator.java
index 512061a..0bd5bc9 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/StringComparator.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/comparator/StringComparator.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
- * 
+ *
  */
 package org.apache.directory.mavibot.btree.comparator;
 
@@ -25,14 +25,25 @@
 
 /**
  * Compares Strings
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class StringComparator implements Comparator<String>
 {
+    /** A static instance of a StringComparator */
+    public static final StringComparator INSTANCE = new StringComparator();
+
+    /**
+     * A private constructor of the StringComparator class
+     */
+    private StringComparator()
+    {
+    }
+
+
     /**
      * Compare two Strings.
-     * 
+     *
      * @param string1 First String
      * @param string2 Second String
      * @return 1 if string1 > String2, 0 if string1 == String2, -1 if string1 < String2
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/FileException.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/FileException.java
new file mode 100644
index 0000000..320a994
--- /dev/null
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/FileException.java
@@ -0,0 +1,72 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree.exception;
+
+
+/**
+ * An exception thrown when there is a problem writing data on disk
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class FileException extends RuntimeException
+{
+    /** The serial version UUID */
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * Creates a new instance of FileException.
+     */
+    public FileException()
+    {
+    }
+
+
+    /**
+     * Creates a new instance of FileException.
+     *
+     * @param explanation The message associated with the exception
+     */
+    public FileException( String explanation )
+    {
+        super( explanation );
+    }
+
+
+    /**
+     * Creates a new instance of FileException.
+     */
+    public FileException( Throwable cause )
+    {
+        super( cause );
+    }
+
+
+    /**
+     * Creates a new instance of FileException.
+     *
+     * @param explanation The message associated with the exception
+     * @param cause The root cause for this exception
+     */
+    public FileException( String explanation, Throwable cause )
+    {
+        super( explanation, cause );
+    }
+}
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/InvalidOffsetException.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/InvalidOffsetException.java
new file mode 100644
index 0000000..c5658c6
--- /dev/null
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/InvalidOffsetException.java
@@ -0,0 +1,72 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree.exception;
+
+
+/**
+ * An exception thrown when the offset is incorrect
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class InvalidOffsetException extends RuntimeException
+{
+    /** The serial version UUID */
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * Creates a new instance of InvalidOffsetException.
+     */
+    public InvalidOffsetException()
+    {
+    }
+
+
+    /**
+     * Creates a new instance of InvalidOffsetException.
+     *
+     * @param explanation The message associated with the exception
+     */
+    public InvalidOffsetException( String explanation )
+    {
+        super( explanation );
+    }
+
+
+    /**
+     * Creates a new instance of InvalidOffsetException.
+     */
+    public InvalidOffsetException( Throwable cause )
+    {
+        super( cause );
+    }
+
+
+    /**
+     * Creates a new instance of BTreeCreationException.
+     *
+     * @param explanation The message associated with the exception
+     * @param cause The root cause for this exception
+     */
+    public InvalidOffsetException( String explanation, Throwable cause )
+    {
+        super( explanation, cause );
+    }
+}
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/KeyNotFoundException.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/KeyNotFoundException.java
index c3c2f1d..d2fcf03 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/KeyNotFoundException.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/KeyNotFoundException.java
@@ -29,6 +29,10 @@
 {
     /** The serial version UUID */
     private static final long serialVersionUID = 1L;
+    
+    /** A static Exception used to avoid creating a new one every time */
+    public static final KeyNotFoundException INSTANCE = new KeyNotFoundException(
+        "Cannot find an entry associated with this key" );
 
 
     /**
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/AbstractElementSerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/AbstractElementSerializer.java
index e525f9c..894f077 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/AbstractElementSerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/AbstractElementSerializer.java
@@ -29,7 +29,7 @@
 
 /**
  * An abstract ElementSerializer that implements comon methods
- * 
+ *
  * @param <T> The type for the element to serialize and compare
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/BooleanSerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/BooleanSerializer.java
index c96d95c..6abdc33 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/BooleanSerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/BooleanSerializer.java
@@ -34,12 +34,15 @@
  */
 public class BooleanSerializer extends AbstractElementSerializer<Boolean>
 {
+    /** A static instance of a BooleanSerializer */
+    public static final BooleanSerializer INSTANCE = new BooleanSerializer();
+
     /**
      * Create a new instance of BooleanSerializer
      */
-    public BooleanSerializer()
+    private BooleanSerializer()
     {
-        super( new BooleanComparator() );
+        super( BooleanComparator.INSTANCE );
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ByteArraySerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ByteArraySerializer.java
index 20512bd..cd78e7f 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ByteArraySerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ByteArraySerializer.java
@@ -35,12 +35,15 @@
  */
 public class ByteArraySerializer extends AbstractElementSerializer<byte[]>
 {
+    /** A static instance of a BytearraySerializer */
+    public static final ByteArraySerializer INSTANCE = new ByteArraySerializer();
+
     /**
      * Create a new instance of ByteArraySerializer
      */
-    public ByteArraySerializer()
+    private ByteArraySerializer()
     {
-        super( new ByteArrayComparator() );
+        super( ByteArrayComparator.INSTANCE );
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ByteSerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ByteSerializer.java
index cbea0f0..425dc38 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ByteSerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ByteSerializer.java
@@ -34,12 +34,15 @@
  */
 public class ByteSerializer extends AbstractElementSerializer<Byte>
 {
+    /** A static instance of a ByteSerializer */
+    public static final ByteSerializer INSTANCE = new ByteSerializer();
+
     /**
      * Create a new instance of ByteSerializer
      */
-    public ByteSerializer()
+    private ByteSerializer()
     {
-        super( new ByteComparator() );
+        super( ByteComparator.INSTANCE );
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/CharArraySerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/CharArraySerializer.java
index 642a9ee..0b54569 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/CharArraySerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/CharArraySerializer.java
@@ -34,12 +34,15 @@
  */
 public class CharArraySerializer extends AbstractElementSerializer<char[]>
 {
+    /** A static instance of a CharArraySerializer */
+    public static final CharArraySerializer INSTANCE = new CharArraySerializer();
+
     /**
      * Create a new instance of CharArraySerializer
      */
-    public CharArraySerializer()
+    private CharArraySerializer()
     {
-        super( new CharArrayComparator() );
+        super( CharArrayComparator.INSTANCE );
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/CharSerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/CharSerializer.java
index c1c45d9..6e443a9 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/CharSerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/CharSerializer.java
@@ -34,12 +34,15 @@
  */
 public class CharSerializer extends AbstractElementSerializer<Character>
 {
+    /** A static instance of a CharSerializer */
+    public static final CharSerializer INSTANCE = new CharSerializer();
+
     /**
      * Create a new instance of CharSerializer
      */
-    public CharSerializer()
+    private CharSerializer()
     {
-        super( new CharComparator() );
+        super( CharComparator.INSTANCE );
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/IntSerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/IntSerializer.java
index 251d9bd..b2a6ea2 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/IntSerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/IntSerializer.java
@@ -34,12 +34,15 @@
  */
 public class IntSerializer extends AbstractElementSerializer<Integer>
 {
+    /** A static instance of a IntSerializer */
+    public static final IntSerializer INSTANCE = new IntSerializer();
+
     /**
      * Create a new instance of IntSerializer
      */
-    public IntSerializer()
+    private IntSerializer()
     {
-        super( new IntComparator() );
+        super( IntComparator.INSTANCE );
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/LongArraySerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/LongArraySerializer.java
index 2cd1f9b..4e32b36 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/LongArraySerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/LongArraySerializer.java
@@ -28,17 +28,20 @@
 
 /**
  * A serializer for a Long[].
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class LongArraySerializer extends AbstractElementSerializer<long[]>
 {
+    /** A static instance of a LongArraySerializer */
+    public static final LongArraySerializer INSTANCE = new LongArraySerializer();
+
     /**
      * Create a new instance of LongSerializer
      */
-    public LongArraySerializer()
+    private LongArraySerializer()
     {
-        super( new LongArrayComparator() );
+        super( LongArrayComparator.INSTANCE );
     }
 
 
@@ -55,32 +58,35 @@
         }
 
         byte[] bytes = null;
+        int pos = 0;
 
         switch ( len )
         {
             case 0:
                 bytes = new byte[4];
 
-                bytes[0] = 0x00;
-                bytes[1] = 0x00;
-                bytes[2] = 0x00;
-                bytes[3] = 0x00;
+                // The number of Long. Here, 0
+                bytes[pos++] = 0x00;
+                bytes[pos++] = 0x00;
+                bytes[pos++] = 0x00;
+                bytes[pos++] = 0x00;
 
                 break;
 
             case -1:
                 bytes = new byte[4];
 
-                bytes[0] = ( byte ) 0xFF;
-                bytes[1] = ( byte ) 0xFF;
-                bytes[2] = ( byte ) 0xFF;
-                bytes[3] = ( byte ) 0xFF;
+                // The number of Long. Here, null
+                bytes[pos++] = ( byte ) 0xFF;
+                bytes[pos++] = ( byte ) 0xFF;
+                bytes[pos++] = ( byte ) 0xFF;
+                bytes[pos++] = ( byte ) 0xFF;
 
                 break;
 
             default:
-                bytes = new byte[len * 8 + 4];
-                int pos = 0;
+                int dataLen = len * 8 + 4;
+                bytes = new byte[dataLen];
 
                 // The number of longs
                 bytes[pos++] = ( byte ) ( len >>> 24 );
@@ -111,11 +117,17 @@
      */
     public long[] deserialize( BufferHandler bufferHandler ) throws IOException
     {
+        // Read the DataLength first. Note that we don't use it here.
         byte[] in = bufferHandler.read( 4 );
 
-        int len = IntSerializer.deserialize( in );
+        IntSerializer.deserialize( in );
 
-        switch ( len )
+        // Now, read the number of Longs
+        in = bufferHandler.read( 4 );
+
+        int nbLongs = IntSerializer.deserialize( in );
+
+        switch ( nbLongs )
         {
             case 0:
                 return new long[]
@@ -125,11 +137,12 @@
                 return null;
 
             default:
-                long[] longs = new long[len];
+                long[] longs = new long[nbLongs];
+                in = bufferHandler.read( nbLongs * 8 );
 
-                int pos = 4;
+                int pos = 0;
 
-                for ( int i = 0; i < len; i++ )
+                for ( int i = 0; i < nbLongs; i++ )
                 {
                     longs[i] = ( ( long ) in[pos++] << 56 ) +
                         ( ( in[pos++] & 0xFFL ) << 48 ) +
@@ -151,9 +164,13 @@
      */
     public long[] deserialize( ByteBuffer buffer ) throws IOException
     {
-        int len = buffer.getInt();
+        // Read the dataLength. Note that we don't use it here.
+        buffer.getInt();
+        
+        // The number of longs
+        int nbLongs = buffer.getInt();
 
-        switch ( len )
+        switch ( nbLongs )
         {
             case 0:
                 return new long[]
@@ -163,9 +180,9 @@
                 return null;
 
             default:
-                long[] longs = new long[len];
+                long[] longs = new long[nbLongs];
 
-                for ( int i = 0; i < len; i++ )
+                for ( int i = 0; i < nbLongs; i++ )
                 {
                     longs[i] = buffer.getLong();
                 }
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/LongSerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/LongSerializer.java
index ae9bf45..1fedd7a 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/LongSerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/LongSerializer.java
@@ -34,12 +34,15 @@
  */
 public class LongSerializer extends AbstractElementSerializer<Long>
 {
+    /** A static instance of a LongSerializer */
+    public final static LongSerializer INSTANCE = new LongSerializer();
+
     /**
      * Create a new instance of LongSerializer
      */
-    public LongSerializer()
+    private LongSerializer()
     {
-        super( new LongComparator() );
+        super( LongComparator.INSTANCE );
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ShortSerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ShortSerializer.java
index f367f31..2f34103 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ShortSerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/ShortSerializer.java
@@ -34,12 +34,15 @@
  */
 public class ShortSerializer extends AbstractElementSerializer<Short>
 {
+    /** A static instance of a ShortSerializer */
+    public final static ShortSerializer INSTANCE = new ShortSerializer();
+
     /**
      * Create a new instance of ShortSerializer
      */
-    public ShortSerializer()
+    private ShortSerializer()
     {
-        super( new ShortComparator() );
+        super( ShortComparator.INSTANCE );
     }
 
 
diff --git a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/StringSerializer.java b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/StringSerializer.java
index f7648c5..1e20f4b 100644
--- a/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/StringSerializer.java
+++ b/mavibot/src/main/java/org/apache/directory/mavibot/btree/serializer/StringSerializer.java
@@ -37,15 +37,15 @@
  */
 public class StringSerializer extends AbstractElementSerializer<String>
 {
+    /** A static instance of a StringSerializer */
     public static final StringSerializer INSTANCE = new StringSerializer();
 
-
     /**
      * Create a new instance of StringSerializer
      */
-    public StringSerializer()
+    private StringSerializer()
     {
-        super( new StringComparator() );
+        super( StringComparator.INSTANCE );
     }
 
 
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeBuilderTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeBuilderTest.java
index b3e90b8..e4e8d22 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeBuilderTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeBuilderTest.java
@@ -27,10 +27,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.directory.mavibot.btree.BTree;
-import org.apache.directory.mavibot.btree.InMemoryBTreeBuilder;
-import org.apache.directory.mavibot.btree.Tuple;
-import org.apache.directory.mavibot.btree.TupleCursor;
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.IntSerializer;
 import org.junit.Test;
 
@@ -43,7 +40,7 @@
 public class InMemoryBTreeBuilderTest
 {
     @Test
-    public void testIntegerTree() throws IOException
+    public void testIntegerTree() throws IOException, KeyNotFoundException
     {
         List<Tuple<Integer, Integer>> sortedTuple = new ArrayList<Tuple<Integer, Integer>>();
 
@@ -53,7 +50,7 @@
             sortedTuple.add( t );
         }
 
-        IntSerializer ser = new IntSerializer();
+        IntSerializer ser = IntSerializer.INSTANCE;
         InMemoryBTreeBuilder<Integer, Integer> bb = new InMemoryBTreeBuilder<Integer, Integer>( "master", 4, ser, ser );
 
         // contains 1, 2, 3, 4, 5, 6, 7
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeConfigurationTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeConfigurationTest.java
index 56fb253..2d48b38 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeConfigurationTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeConfigurationTest.java
@@ -25,8 +25,6 @@
 import java.io.File;
 import java.io.IOException;
 
-import org.apache.directory.mavibot.btree.BTree;
-import org.apache.directory.mavibot.btree.InMemoryBTree;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.IntSerializer;
 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
@@ -37,7 +35,7 @@
 
 /**
  * Test the creation of a BTree with a configuration.
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class InMemoryBTreeConfigurationTest
@@ -123,7 +121,7 @@
         InMemoryBTreeConfiguration<Integer, String> config = new InMemoryBTreeConfiguration<Integer, String>();
         config.setName( "basic" );
         config.setPageSize( 32 );
-        config.setSerializers( new IntSerializer(), new StringSerializer() );
+        config.setSerializers( IntSerializer.INSTANCE, StringSerializer.INSTANCE );
 
         try
         {
@@ -170,7 +168,7 @@
 
 
     /**
-     * Test the creation of a BTree using the BTreeConfiguration, flushing the 
+     * Test the creation of a BTree using the BTreeConfiguration, flushing the
      * tree on disk, then reloading it in another BTree.
      */
     @Test
@@ -184,7 +182,7 @@
         {
             InMemoryBTreeConfiguration<Integer, String> config = new InMemoryBTreeConfiguration<Integer, String>();
             config.setPageSize( 32 );
-            config.setSerializers( new IntSerializer(), new StringSerializer() );
+            config.setSerializers( IntSerializer.INSTANCE, StringSerializer.INSTANCE );
 
             config.setFilePath( parent );
             config.setName( "mavibot" );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeDuplicateKeyTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeDuplicateKeyTest.java
index 8da7604..68b7a88 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeDuplicateKeyTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeDuplicateKeyTest.java
@@ -33,6 +33,7 @@
 
 import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
 import org.apache.directory.mavibot.btree.exception.DuplicateValueNotAllowedException;
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.IntSerializer;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
@@ -47,9 +48,9 @@
 public class InMemoryBTreeDuplicateKeyTest
 {
     @Test
-    public void testInsertNullValue() throws IOException
+    public void testInsertNullValue() throws IOException, KeyNotFoundException
     {
-        IntSerializer serializer = new IntSerializer();
+        IntSerializer serializer = IntSerializer.INSTANCE;
 
         BTree<Integer, Integer> btree = BTreeFactory.createInMemoryBTree( "master", serializer, serializer );
 
@@ -69,9 +70,9 @@
 
 
     @Test
-    public void testBrowseEmptyTree() throws IOException
+    public void testBrowseEmptyTree() throws IOException, KeyNotFoundException
     {
-        IntSerializer serializer = new IntSerializer();
+        IntSerializer serializer = IntSerializer.INSTANCE;
 
         BTree<Integer, Integer> btree = BTreeFactory.createInMemoryBTree( "master", serializer, serializer );
 
@@ -105,9 +106,9 @@
 
 
     @Test
-    public void testDuplicateKey() throws IOException
+    public void testDuplicateKey() throws IOException, KeyNotFoundException
     {
-        IntSerializer serializer = new IntSerializer();
+        IntSerializer serializer = IntSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
         config.setAllowDuplicates( true );
@@ -163,7 +164,7 @@
     @Test
     public void testGetDuplicateKey() throws Exception
     {
-        IntSerializer serializer = new IntSerializer();
+        IntSerializer serializer = IntSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
         config.setAllowDuplicates( true );
@@ -199,7 +200,7 @@
     @Test
     public void testRemoveDuplicateKey() throws Exception
     {
-        IntSerializer serializer = new IntSerializer();
+        IntSerializer serializer = IntSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
         config.setAllowDuplicates( true );
@@ -235,7 +236,7 @@
     @Test
     public void testFullPage() throws Exception
     {
-        StringSerializer serializer = new StringSerializer();
+        StringSerializer serializer = StringSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<String, String> config = new InMemoryBTreeConfiguration<String, String>();
         config.setAllowDuplicates( true );
@@ -298,7 +299,7 @@
     @Test
     public void testMoveFirst() throws Exception
     {
-        StringSerializer serializer = new StringSerializer();
+        StringSerializer serializer = StringSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<String, String> config = new InMemoryBTreeConfiguration<String, String>();
         config.setAllowDuplicates( true );
@@ -387,7 +388,7 @@
     @Test(expected = NoSuchElementException.class)
     public void testMoveLast() throws Exception
     {
-        StringSerializer serializer = new StringSerializer();
+        StringSerializer serializer = StringSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<String, String> config = new InMemoryBTreeConfiguration<String, String>();
         config.setAllowDuplicates( true );
@@ -433,7 +434,7 @@
     @Test(expected = NoSuchElementException.class)
     public void testNextPrevKey() throws Exception
     {
-        StringSerializer serializer = new StringSerializer();
+        StringSerializer serializer = StringSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<String, String> config = new InMemoryBTreeConfiguration<String, String>();
         config.setAllowDuplicates( true );
@@ -546,7 +547,7 @@
     @Test
     public void testMoveToNextAndPrevWithPageBoundaries() throws Exception
     {
-        IntSerializer serializer = new IntSerializer();
+        IntSerializer serializer = IntSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
         config.setAllowDuplicates( true );
@@ -621,7 +622,7 @@
     @Test
     public void testNextAfterPrev() throws Exception
     {
-        IntSerializer serializer = new IntSerializer();
+        IntSerializer serializer = IntSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
         config.setAllowDuplicates( true );
@@ -667,7 +668,7 @@
     @Test
     public void testMoveToNextAndTraverseBackward() throws Exception
     {
-        IntSerializer serializer = new IntSerializer();
+        IntSerializer serializer = IntSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
         config.setAllowDuplicates( true );
@@ -706,7 +707,7 @@
     @Test
     public void testMoveToPrevAndTraverseForward() throws Exception
     {
-        IntSerializer serializer = new IntSerializer();
+        IntSerializer serializer = IntSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
         config.setAllowDuplicates( true );
@@ -744,8 +745,8 @@
     @Test(expected = DuplicateValueNotAllowedException.class)
     public void testBTreeForbidDups() throws IOException, BTreeAlreadyManagedException
     {
-        BTree<Long, String> singleValueBtree = BTreeFactory.createInMemoryBTree( "test2", new LongSerializer(),
-            new StringSerializer(), BTree.FORBID_DUPLICATES );
+        BTree<Long, String> singleValueBtree = BTreeFactory.createInMemoryBTree( "test2", LongSerializer.INSTANCE,
+            StringSerializer.INSTANCE, BTree.FORBID_DUPLICATES );
 
         for ( long i = 0; i < 64; i++ )
         {
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeFlushTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeFlushTest.java
index 5ffcc2a..7946378 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeFlushTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeFlushTest.java
@@ -29,10 +29,6 @@
 import java.util.Random;
 import java.util.Set;
 
-import org.apache.directory.mavibot.btree.BTree;
-import org.apache.directory.mavibot.btree.InMemoryBTree;
-import org.apache.directory.mavibot.btree.Tuple;
-import org.apache.directory.mavibot.btree.TupleCursor;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.IntSerializer;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
@@ -44,7 +40,7 @@
 
 /**
  * A unit test class for BTree flush() operation
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class InMemoryBTreeFlushTest
@@ -132,8 +128,8 @@
         long delta = l1;
         int nbElems = 100000;
 
-        BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", new LongSerializer(),
-            new StringSerializer() );
+        BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 32 );
 
         for ( int i = 0; i < nbElems; i++ )
@@ -224,8 +220,8 @@
         // Create a BTree with pages containing 8 elements
         String path = tempFolder.getRoot().getCanonicalPath();
 
-        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", path, new IntSerializer(),
-            new StringSerializer() );
+        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", path, IntSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 8 );
 
         File journal = ( ( InMemoryBTree<Integer, String> ) btree ).getJournal();
@@ -251,8 +247,8 @@
             assertEquals( 0, journal.length() );
 
             // Load the data into a new tree
-            BTree<Integer, String> btreeLoaded = BTreeFactory.createInMemoryBTree( "test", path, new IntSerializer(),
-                new StringSerializer() );
+            BTree<Integer, String> btreeLoaded = BTreeFactory.createInMemoryBTree( "test", path, IntSerializer.INSTANCE,
+                StringSerializer.INSTANCE );
             btree.setPageSize( 8 );
 
             TupleCursor<Integer, String> cursor1 = btree.browse();
@@ -294,8 +290,8 @@
         BTree<Long, String> btree = BTreeFactory.createInMemoryBTree(
             "test",
             dataFile.getParent(),
-            new LongSerializer(),
-            new StringSerializer() );
+            LongSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 32 );
         btree.close();
     }
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeTest.java
index 5cb2a81..f32cebf 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeTest.java
@@ -168,8 +168,8 @@
 
         for ( int j = 0; j < nbTrees; j++ )
         {
-            BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", new LongSerializer(),
-                new StringSerializer() );
+            BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
+                StringSerializer.INSTANCE );
             btree.setPageSize( 32 );
 
             for ( int i = 0; i < nbElems; i++ )
@@ -271,8 +271,8 @@
 
         for ( int j = 0; j < nbTrees; j++ )
         {
-            BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", new LongSerializer(),
-                new StringSerializer() );
+            BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
+                StringSerializer.INSTANCE );
             btree.setPageSize( 8 );
 
             for ( int i = 0; i < nbElems; i++ )
@@ -387,8 +387,8 @@
                 368, 245, 1005, 226, 939, 320, 396, 437, 373, 61
         };
 
-        BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", new LongSerializer(),
-            new StringSerializer() );
+        BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 8 );
 
         for ( long value : values )
@@ -447,8 +447,8 @@
 
         Random random = new Random( System.nanoTime() );
 
-        BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", new LongSerializer(),
-            new StringSerializer() );
+        BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 8 );
 
         // Insert some values
@@ -508,8 +508,8 @@
     @Ignore("This is a debug test")
     public void testPageInsertDebug() throws Exception
     {
-        BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", new LongSerializer(),
-            new StringSerializer() );
+        BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 4 );
 
         Long[] elems = new Long[]
@@ -615,8 +615,8 @@
     public void testBrowseForward() throws Exception
     {
         // Create a BTree with pages containing 8 elements
-        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", new IntSerializer(),
-            new StringSerializer() );
+        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 8 );
 
         // Inject the values
@@ -700,8 +700,8 @@
     public void testBrowseBackward() throws Exception
     {
         // Create a BTree with pages containing 8 elements
-        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", new IntSerializer(),
-            new StringSerializer() );
+        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 8 );
 
         // Inject the values
@@ -776,8 +776,8 @@
     public void testBrowseEmptyTree() throws Exception
     {
         // Create a BTree with pages containing 8 elements
-        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", new IntSerializer(),
-            new StringSerializer() );
+        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 8 );
 
         TupleCursor<Integer, String> cursor = btree.browse();
@@ -797,8 +797,8 @@
     public void testBrowseForwardBackward() throws Exception
     {
         // Create a BTree with pages containing 4 elements
-        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", new IntSerializer(),
-            new StringSerializer() );
+        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 4 );
 
         for ( int i = 0; i < 16; i++ )
@@ -911,7 +911,7 @@
      * Test the exist() method
      */
     @Test
-    public void testExist() throws IOException
+    public void testExist() throws IOException, KeyNotFoundException
     {
         // Create a BTree with pages containing 4 elements
         BTree<Integer, String> btree = createTwoLevelBTreeFullLeaves();
@@ -1026,8 +1026,8 @@
     public void testBrowseNonExistingKey() throws Exception
     {
         // Create a BTree with pages containing 8 elements
-        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", new IntSerializer(),
-            new StringSerializer() );
+        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 8 );
         for ( int i = 0; i < 11; i++ )
         {
@@ -1091,8 +1091,8 @@
      */
     private BTree<Integer, String> createTwoLevelBTreeFullLeaves() throws IOException
     {
-        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", new IntSerializer(),
-            new StringSerializer() );
+        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 4 );
 
         // Create a tree with 5 children containing 4 elements each. The tree is full.
@@ -1114,8 +1114,8 @@
      */
     private BTree<Integer, String> createTwoLevelBTreeHalfFullLeaves() throws IOException
     {
-        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", new IntSerializer(),
-            new StringSerializer() );
+        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 4 );
 
         // Create a tree with 5 children containing 4 elements each. The tree is full.
@@ -1146,8 +1146,8 @@
         // Create a BTree with pages containing 4 elements
         int pageSize = 4;
 
-        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", new IntSerializer(),
-            new StringSerializer(),
+        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
+            StringSerializer.INSTANCE,
             pageSize );
 
         InMemoryNode<Integer, String> root = new InMemoryNode<Integer, String>( btree, 1L, pageSize );
@@ -1193,7 +1193,7 @@
      * @param element The removed element
      * @param expected The expected set of elements
      */
-    private void checkRemoval( BTree<Integer, String> btree, int element, Set<Integer> expected ) throws IOException
+    private void checkRemoval( BTree<Integer, String> btree, int element, Set<Integer> expected ) throws IOException, KeyNotFoundException
     {
         Tuple<Integer, String> removed = btree.delete( element );
         assertEquals( element, removed.getKey().intValue() );
@@ -1213,7 +1213,7 @@
      * @param btree The tree to check
      * @param expected The set with the expected elements
      */
-    private void checkTree( BTree<Integer, String> btree, Set<Integer> expected )
+    private void checkTree( BTree<Integer, String> btree, Set<Integer> expected ) throws KeyNotFoundException
     {
         try
         {
@@ -1723,7 +1723,7 @@
      * Test the addition of elements with null values
      */
     @Test
-    public void testAdditionNullValues() throws IOException
+    public void testAdditionNullValues() throws IOException, KeyNotFoundException
     {
         BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
 
@@ -1766,8 +1766,8 @@
         long delta = System.currentTimeMillis();
 
         // Create a BTree with 5 million entries
-        BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", new LongSerializer(),
-            new StringSerializer() );
+        BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 32 );
 
         for ( int i = 0; i < nbElems; i++ )
@@ -1869,8 +1869,8 @@
     public void testBrowseForwardBackwardExtremes() throws Exception
     {
         // Create a BTree with pages containing 4 elements
-        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", new IntSerializer(),
-            new StringSerializer() );
+        BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
+            StringSerializer.INSTANCE );
         btree.setPageSize( 4 );
 
         for ( int i = 8; i < 13; i++ )
@@ -1925,7 +1925,7 @@
     @Test
     public void testNextAfterPrev() throws Exception
     {
-        IntSerializer serializer = new IntSerializer();
+        IntSerializer serializer = IntSerializer.INSTANCE;
 
         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
         config.setName( "master" );
@@ -1965,7 +1965,7 @@
     @Test
     public void testCheckRootPageContents() throws Exception
     {
-        IntSerializer ser = new IntSerializer();
+        IntSerializer ser = IntSerializer.INSTANCE;
         BTree<Integer, Integer> btree = BTreeFactory.createInMemoryBTree( "master1", ser, ser, 4 );
 
         for ( int i = 1; i < 8; i++ )
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeTestOps.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeTestOps.java
index 33235c6..c887c71 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeTestOps.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeTestOps.java
@@ -23,7 +23,6 @@
 import java.io.IOException;
 import java.util.Random;
 
-import org.apache.directory.mavibot.btree.BTree;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
 import org.junit.AfterClass;
@@ -33,7 +32,7 @@
 
 /**
  * A class to test multi-threaded operations on the btree
- *  
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class InMemoryBTreeTestOps
@@ -49,7 +48,7 @@
     @BeforeClass
     public static void setup() throws IOException
     {
-        btree = BTreeFactory.createInMemoryBTree( "test", new LongSerializer(), new StringSerializer() );
+        btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE, StringSerializer.INSTANCE );
     }
 
 
@@ -71,7 +70,7 @@
     {
         Random random = new Random( System.nanoTime() );
 
-        int nbElems = 500000;
+        int nbElems = 50000;
 
         // Create a BTree with 500 000 entries
         btree.setPageSize( 32 );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryLeafTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryLeafTest.java
index d5deaec..2f6786e 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryLeafTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryLeafTest.java
@@ -26,18 +26,6 @@
 
 import java.io.IOException;
 
-import org.apache.directory.mavibot.btree.BTree;
-import org.apache.directory.mavibot.btree.BorrowedFromLeftResult;
-import org.apache.directory.mavibot.btree.BorrowedFromRightResult;
-import org.apache.directory.mavibot.btree.DeleteResult;
-import org.apache.directory.mavibot.btree.InsertResult;
-import org.apache.directory.mavibot.btree.KeyHolder;
-import org.apache.directory.mavibot.btree.MergedWithSiblingResult;
-import org.apache.directory.mavibot.btree.NotPresentResult;
-import org.apache.directory.mavibot.btree.Page;
-import org.apache.directory.mavibot.btree.PageHolder;
-import org.apache.directory.mavibot.btree.RemoveResult;
-import org.apache.directory.mavibot.btree.Tuple;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
@@ -48,7 +36,7 @@
 
 /**
  * A unit test class for Leaf
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class InMemoryLeafTest
@@ -62,7 +50,7 @@
     @Before
     public void setup() throws IOException
     {
-        btree = BTreeFactory.createInMemoryBTree( "test", new LongSerializer(), new StringSerializer() );
+        btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE, StringSerializer.INSTANCE );
         btree.setPageSize( 8 );
     }
 
@@ -76,12 +64,12 @@
 
     /**
      * A helper method to insert elements in a Leaf
-     * @throws IOException 
+     * @throws IOException
      */
     private InMemoryLeaf<Long, String> insert( InMemoryLeaf<Long, String> leaf, long key, String value )
         throws IOException
     {
-        InsertResult<Long, String> result = leaf.insert( 1L, key, value );
+        InsertResult<Long, String> result = leaf.insert( key, value, 1L );
 
         return ( InMemoryLeaf<Long, String> ) ( ( ModifyResult<Long, String> ) result ).getModifiedPage();
     }
@@ -96,7 +84,7 @@
     {
         InMemoryLeaf<Long, String> leaf = new InMemoryLeaf<Long, String>( btree );
 
-        DeleteResult<Long, String> result = leaf.delete( 1L, 1L, null, null, -1 );
+        DeleteResult<Long, String> result = leaf.delete( 1L, null, 1L, null, -1 );
 
         assertEquals( NotPresentResult.NOT_PRESENT, result );
     }
@@ -115,7 +103,7 @@
         leaf = insert( leaf, 3L, "v3" );
         leaf = insert( leaf, 4L, "v4" );
 
-        DeleteResult<Long, String> result = leaf.delete( 2L, 5L, null, null, -1 );
+        DeleteResult<Long, String> result = leaf.delete( 5L, null, 2L, null, -1 );
 
         assertEquals( NotPresentResult.NOT_PRESENT, result );
     }
@@ -134,7 +122,7 @@
         leaf = insert( leaf, 3L, "v3" );
         leaf = insert( leaf, 4L, "v4" );
 
-        DeleteResult<Long, String> result = leaf.delete( 4L, 3L, null, null, -1 );
+        DeleteResult<Long, String> result = leaf.delete( 3L, null, 4L, null, -1 );
 
         assertTrue( result instanceof RemoveResult );
 
@@ -181,7 +169,7 @@
         leaf = insert( leaf, 3L, "v3" );
         leaf = insert( leaf, 4L, "v4" );
 
-        DeleteResult<Long, String> result = leaf.delete( 4L, 1L, null, null, -1 );
+        DeleteResult<Long, String> result = leaf.delete( 1L, null, 4L, null, -1 );
 
         assertTrue( result instanceof RemoveResult );
 
@@ -224,7 +212,7 @@
      *            +--[1, 2, 3, 4, 5]
      * [6, 10]-+--[6, 7, 8, 9]
      *            +--[10, 11, 12, 13]
-     * @throws IOException 
+     * @throws IOException
      */
     @Test
     public void testDeleteBorrowingFromLeftSibling() throws IOException
@@ -262,7 +250,7 @@
         parent.setKey( 1, new KeyHolder<Long>( 10L ) );
 
         // Now, delete the element from the target page
-        DeleteResult<Long, String> result = target.delete( 2L, 7L, null, parent, 1 );
+        DeleteResult<Long, String> result = target.delete( 7L, null, 2L, parent, 1 );
 
         assertTrue( result instanceof BorrowedFromLeftResult );
 
@@ -294,7 +282,7 @@
     /**
      * Check that deleting an element from a leaf with N/2 element works when we borrow
      * an element in a right page with more than N/2 elements
-     * @throws IOException 
+     * @throws IOException
      */
     @Test
     public void testDeleteBorrowingFromRightSibling() throws IOException
@@ -332,7 +320,7 @@
         parent.setKey( 1, new KeyHolder<Long>( 10L ) );
 
         // Now, delete the element from the target page
-        DeleteResult<Long, String> result = target.delete( 2L, 7L, null, parent, 1 );
+        DeleteResult<Long, String> result = target.delete( 7L, null, 2L, parent, 1 );
 
         assertTrue( result instanceof BorrowedFromRightResult );
 
@@ -365,7 +353,7 @@
     /**
      * Check that deleting an element from a leaf with N/2 element works when we merge
      * it with one of its sibling, if both has N/2 elements
-     * @throws IOException 
+     * @throws IOException
      */
     @Test
     public void testDeleteMergeWithSibling() throws IOException
@@ -402,7 +390,7 @@
         parent.setKey( 1, new KeyHolder<Long>( 9L ) );
 
         // Now, delete the element from the target page
-        DeleteResult<Long, String> result = target.delete( 2L, 7L, null, parent, 1 );
+        DeleteResult<Long, String> result = target.delete( 7L, null, 2L, parent, 1 );
 
         assertTrue( result instanceof MergedWithSiblingResult );
 
@@ -438,7 +426,7 @@
         for ( long i = 0; i < 8; i++ )
         {
             long value = i + i + 1;
-            leaf = ( InMemoryLeaf<Long, String> ) ( ( ModifyResult<Long, String> ) leaf.insert( 0L, value, "V" + value ) )
+            leaf = ( InMemoryLeaf<Long, String> ) ( ( ModifyResult<Long, String> ) leaf.insert( value, "V" + value, 0L ) )
                 .getModifiedPage();
         }
 
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/MultiThreadedInMemoryBtreeTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/MultiThreadedInMemoryBtreeTest.java
index 7d969d4..26e70b6 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/MultiThreadedInMemoryBtreeTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/MultiThreadedInMemoryBtreeTest.java
@@ -21,26 +21,24 @@
 
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
 
 import java.io.IOException;
 import java.util.Random;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.apache.directory.mavibot.btree.BTree;
-import org.apache.directory.mavibot.btree.Tuple;
-import org.apache.directory.mavibot.btree.TupleCursor;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.Ignore;
 
 
 /**
  * A class to test multi-threaded operations on the btree
- *  
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class MultiThreadedInMemoryBtreeTest
@@ -56,7 +54,7 @@
     @BeforeClass
     public static void setup() throws IOException
     {
-        btree = BTreeFactory.createInMemoryBTree( "test", new LongSerializer(), new StringSerializer() );
+        btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE, StringSerializer.INSTANCE );
     }
 
 
@@ -110,10 +108,10 @@
 
     /**
      * Browse the btree in its current revision, reading all of its elements
-     * @return The number of read elements 
+     * @return The number of read elements
      * @throws IOException If the browse failed
      */
-    private int testBrowse() throws IOException
+    private int testBrowse() throws IOException, KeyNotFoundException
     {
         TupleCursor<Long, String> cursor = btree.browse();
 
@@ -140,7 +138,7 @@
     /**
      * Check that we can read the btree while it is being modified. We will start
      * 100 readers for one writer.
-     * 
+     *
      * @throws InterruptedException If the btree access failed.
      */
     @Test
@@ -217,42 +215,62 @@
     {
         int nbThreads = 100;
         final CountDownLatch latch = new CountDownLatch( nbThreads );
+        final AtomicBoolean error = new AtomicBoolean(false);
 
         //Thread.sleep( 60000L );
 
         long t0 = System.currentTimeMillis();
 
+        class MyThread extends Thread
+        {
+            private int prefix = 0;
+
+            public void run()
+            {
+                try
+                {
+                    // Inject 1000 elements
+                    for ( int j = 0; j < 1000; j++ )
+                    {
+                        long value = prefix * 1000 + j;
+                        String valStr = Long.toString( value );
+                        //System.out.println( "---------------------------Inserting " + valStr + " for Thread " + Thread.currentThread().getName() );
+                        btree.insert( value, valStr );
+
+                        if ( j % 100 == 0 )
+                        {
+                            //System.out.println( "---------------------------Inserting " + valStr + " for Thread " + Thread.currentThread().getName() );
+//                            long res = checkBtree( prefix, 1000, j );
+//
+//                            if ( res != -1L )
+//                            {
+//                                //retry
+//                                System.out.println( "Failure to retrieve " + j );
+//                                latch.countDown();
+//                                error.set( true );
+//                                return;
+//                            }
+                        }
+                    }
+
+                    latch.countDown();
+                }
+                catch ( Exception e )
+                {
+                    e.printStackTrace();
+                    System.out.println( e.getMessage() );
+                }
+            }
+
+            public MyThread( int prefix )
+            {
+                this.prefix = prefix;
+            }
+        }
+
         for ( int i = 0; i < nbThreads; i++ )
         {
-            final long prefix = i;
-            Thread test = new Thread()
-            {
-                public void run()
-                {
-                    try
-                    {
-                        // Inject 1000 elements
-                        for ( int j = 0; j < 1000; j++ )
-                        {
-                            long value = prefix * 1000 + j;
-                            btree.insert( value, Long.toString( value ) );
-
-                            /*
-                            if ( j % 10000 == 0 )
-                            {
-                                System.out.println( "Thread " + Thread.currentThread().getName() + " flushed " + j
-                                    + " elements" );
-                            }
-                            */
-                        }
-
-                        latch.countDown();
-                    }
-                    catch ( Exception e )
-                    {
-                    }
-                }
-            };
+            MyThread test = new MyThread( i );
 
             // Start each reader
             test.start();
@@ -261,22 +279,65 @@
         // Wait for all the readers to be done
         latch.await();
 
+        if ( error.get() )
+        {
+            System.out.println( "ERROR -----------------" );
+            return;
+        }
+
         long t1 = System.currentTimeMillis();
 
         // Check that the tree contains all the values
+        assertEquals( -1L, checkBtree( 1000, nbThreads ) );
+
+        System.out.println( " Time to create 1M entries : "
+            + ( ( t1 - t0 ) ) + " milliseconds" );
+    }
+
+
+    private long checkBtree( int prefix, int nbElems, int currentElem ) throws IOException
+    {
+        long i = 0L;
+
         try
         {
-            for ( long i = 0L; i < 10000L; i++ )
+            for ( i = 0L; i < currentElem; i++ )
             {
-                assertEquals( Long.toString( i ), btree.get( i ) );
+                long key = prefix * nbElems + i;
+                assertEquals( Long.toString( key ), btree.get( key ) );
             }
+
+            return -1L;
         }
         catch ( KeyNotFoundException knfe )
         {
-            fail();
+            System.out.println( "cannot find " + ( prefix * nbElems + i ) );
+            return i;
         }
+    }
 
-        System.out.println( " Time to create 1M entries : "
-            + ( ( t1 - t0 ) / 1000 ) + " seconds" );
+
+    private long checkBtree( int nbElems, int nbThreads ) throws IOException
+    {
+        long i = 0L;
+
+        try
+        {
+            for ( long j = 0; j < nbThreads; j++ )
+            {
+                for ( i = 0L; i < nbElems; i++ )
+                {
+                    long key = j * nbElems + i;
+                    assertEquals( Long.toString( key ), btree.get( key ) );
+                }
+            }
+
+            return -1L;
+        }
+        catch ( KeyNotFoundException knfe )
+        {
+            System.out.println( "cannot find " + i );
+            return i;
+        }
     }
 }
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeBrowseTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeBrowseTest.java
index 8f34cac..f393b86 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeBrowseTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeBrowseTest.java
@@ -32,16 +32,14 @@
 import java.util.UUID;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.directory.mavibot.btree.BTree;
-import org.apache.directory.mavibot.btree.RecordManager;
-import org.apache.directory.mavibot.btree.Tuple;
-import org.apache.directory.mavibot.btree.TupleCursor;
 import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
 import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -49,7 +47,7 @@
 
 /**
  * Tests the browse methods on a managed BTree
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class PersistedBTreeBrowseTest
@@ -77,7 +75,7 @@
         try
         {
             // Create a new BTree which allows duplicate values
-            btree = recordManager1.addBTree( "test", new LongSerializer(), new StringSerializer(), true );
+            btree = recordManager1.addBTree( "test", LongSerializer.INSTANCE, StringSerializer.INSTANCE, true );
         }
         catch ( Exception e )
         {
@@ -196,10 +194,11 @@
     // The Browse tests
     //----------------------------------------------------------------------------------------
     /**
-     * Test the browse methods on an empty btree  
+     * Test the browse methods on an empty btree
+     * @throws KeyNotFoundException 
      */
     @Test
-    public void testBrowseEmptyBTree() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseEmptyBTree() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         TupleCursor<Long, String> cursor = btree.browse();
 
@@ -226,7 +225,7 @@
             // Expected
         }
 
-        assertEquals( -1L, cursor.getRevision() );
+        assertEquals( 0L, cursor.getRevision() );
     }
 
 
@@ -234,7 +233,7 @@
      * Test the browse methods on a btree containing just a leaf
      */
     @Test
-    public void testBrowseBTreeLeafNext() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeLeafNext() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some data
         btree.insert( 1L, "1" );
@@ -264,7 +263,7 @@
      * Test the browse methods on a btree containing just a leaf
      */
     @Test
-    public void testBrowseBTreeLeafPrev() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeLeafPrev() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some data
         btree.insert( 1L, "1" );
@@ -292,7 +291,7 @@
      * move at the end or at the beginning
      */
     @Test
-    public void testBrowseBTreeLeafFirstLast() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeLeafFirstLast() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some data
         btree.insert( 1L, "1" );
@@ -374,7 +373,7 @@
      * move back and forth
      */
     @Test
-    public void testBrowseBTreeLeafNextPrev() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeLeafNextPrev() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some data
         btree.insert( 1L, "1" );
@@ -426,7 +425,7 @@
      * Test the browse methods on a btree containing many nodes
      */
     @Test
-    public void testBrowseBTreeNodesNext() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeNodesNext() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some data
         for ( long i = 1; i < 1000L; i++ )
@@ -458,7 +457,7 @@
      * Test the browse methods on a btree containing many nodes
      */
     @Test
-    public void testBrowseBTreeNodesPrev() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeNodesPrev() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some data
         for ( long i = 1; i < 1000L; i++ )
@@ -490,7 +489,7 @@
      * Test the browse methods on a btree containing just a leaf with duplicate values
      */
     @Test
-    public void testBrowseBTreeLeafNextDups1() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeLeafNextDups1() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some duplicate data
         btree.insert( 1L, "1" );
@@ -520,7 +519,7 @@
      * Test the browse methods on a btree containing just a leaf with duplicate values
      */
     @Test
-    public void testBrowseBTreeLeafNextDupsN() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeLeafNextDupsN() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some duplicate data
         btree.insert( 1L, "1" );
@@ -554,7 +553,7 @@
      * Test the browse methods on a btree containing just a leaf with duplicate values
      */
     @Test
-    public void testBrowseBTreeLeafPrevDups1() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeLeafPrevDups1() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some duplicate data
         btree.insert( 1L, "1" );
@@ -584,7 +583,7 @@
      * Test the browse methods on a btree containing just a leaf with duplicate values
      */
     @Test
-    public void testBrowseBTreeLeafPrevDupsN() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeLeafPrevDupsN() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some duplicate data
         btree.insert( 1L, "1" );
@@ -618,7 +617,7 @@
      * Test the browse methods on a btree containing nodes with duplicate values
      */
     @Test
-    public void testBrowseBTreeNodesNextDupsN() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeNodesNextDupsN() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some data
         for ( long i = 1; i < 1000L; i++ )
@@ -664,7 +663,7 @@
      * Test the browse methods on a btree containing nodes with duplicate values
      */
     @Test
-    public void testBrowseBTreeNodesPrevDupsN() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeNodesPrevDupsN() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some data
         for ( long i = 1; i < 1000L; i++ )
@@ -711,7 +710,7 @@
      * stored into a sub btree
      */
     @Test
-    public void testBrowseBTreeLeafNextDupsSubBTree1() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeLeafNextDupsSubBTree1() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some duplicate data which will be stored into a sub btree
         for ( long i = 1L; i < 32L; i++ )
@@ -743,7 +742,7 @@
      * Test the browse methods on a btree containing just a leaf with duplicate values
      */
     @Test
-    public void testBrowseBTreeLeafPrevDupsSubBTree1() throws IOException, BTreeAlreadyManagedException
+    public void testBrowseBTreeLeafPrevDupsSubBTree1() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some duplicate data which will be stored into a sub btree
         for ( long i = 1L; i < 32L; i++ )
@@ -805,7 +804,7 @@
             // Expected
         }
 
-        assertEquals( -1L, cursor.getRevision() );
+        assertEquals( 0L, cursor.getRevision() );
     }
 
 
@@ -893,6 +892,27 @@
 
 
     /**
+     * Test the browseFrom method on a btree with a non existing key
+     */
+    @Test
+    public void testBrowseFromBTreeNodesNotExistingKey() throws IOException, BTreeAlreadyManagedException
+    {
+        // Inject some data
+        for ( long i = 0; i <= 1000L; i += 2 )
+        {
+            btree.insert( i, Long.toString( i ) );
+        }
+
+        // Create the cursor
+        TupleCursor<Long, String> cursor = btree.browseFrom( 1500L );
+        
+        assertFalse( cursor.hasNext() );
+        assertTrue( cursor.hasPrev() );
+        assertEquals( 1000L, cursor.prev().getKey().longValue() );
+    }
+
+
+    /**
      * Test the browseFrom method on a btree containing nodes with duplicate values
      */
     @Test
@@ -936,11 +956,11 @@
     // The TupleCursor.moveToNext/PrevNonDuplicateKey method tests
     //----------------------------------------------------------------------------------------
     /**
-      * Test the TupleCursor.nextKey method on a btree containing nodes 
+      * Test the TupleCursor.nextKey method on a btree containing nodes
       * with duplicate values.
       */
     @Test
-    public void testNextKey() throws IOException, BTreeAlreadyManagedException
+    public void testNextKey() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some data
         for ( long i = 1; i < 1000L; i++ )
@@ -983,13 +1003,63 @@
         }
     }
 
+    
+    /**
+     * Test the TupleCursor.nextKey method on a btree containing nodes
+     * with duplicate values.
+     */
+   @Test
+   @Ignore
+   public void testNextKeyDups() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
+   {
+       // Inject some data
+       //for ( long i = 1; i < 3; i++ )
+       {
+           for ( long j = 1; j < 9; j++ )
+           {
+               btree.insert( 1L, Long.toString( j ) );
+           }
+       }
+
+       btree.insert( 1L, "10" );
+
+       // Create the cursor
+       TupleCursor<Long, String> cursor = btree.browse();
+
+       // Move forward
+       cursor.beforeFirst();
+
+       assertFalse( cursor.hasPrevKey() );
+       assertTrue( cursor.hasNextKey() );
+
+       Tuple<Long, String> tuple = cursor.nextKey();
+
+       checkTuple( tuple, 1L, "1" );
+       
+       cursor.beforeFirst();
+       long val = 1L;
+       
+       while ( cursor.hasNext() )
+       {
+           tuple = cursor.next();
+           
+           assertEquals( Long.valueOf( 1L ), tuple.getKey() );
+           assertEquals( Long.toString( val ), tuple.getValue() );
+           
+           val++;
+       }
+       
+       assertFalse( cursor.hasNextKey() );
+       assertFalse( cursor.hasPrevKey() );
+   }
+
 
     /**
-     * Test the TupleCursor.moveToPrevNonDuplicateKey method on a btree containing nodes 
+     * Test the TupleCursor.moveToPrevNonDuplicateKey method on a btree containing nodes
      * with duplicate values.
      */
     @Test
-    public void testPrevKey() throws IOException, BTreeAlreadyManagedException
+    public void testPrevKey() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         // Inject some data
         for ( long i = 1; i < 1000L; i++ )
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilderTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilderTest.java
index 8f98e3a..6552d8d 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilderTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilderTest.java
@@ -27,12 +27,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.directory.mavibot.btree.BTree;
-import org.apache.directory.mavibot.btree.PersistedBTreeBuilder;
-import org.apache.directory.mavibot.btree.RecordManager;
-import org.apache.directory.mavibot.btree.Tuple;
-import org.apache.directory.mavibot.btree.TupleCursor;
 import org.apache.directory.mavibot.btree.serializer.IntSerializer;
+import org.junit.Ignore;
 import org.junit.Test;
 
 
@@ -41,6 +37,7 @@
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
+@Ignore( "until ApacheDS works with mavibot" )
 public class PersistedBTreeBuilderTest
 {
 
@@ -60,7 +57,7 @@
 
         RecordManager rm = new RecordManager( file.getAbsolutePath() );
 
-        IntSerializer ser = new IntSerializer();
+        IntSerializer ser = IntSerializer.INSTANCE;
         PersistedBTreeBuilder<Integer, Integer> bb = new PersistedBTreeBuilder<Integer, Integer>( rm, "master", 4, ser,
             ser );
 
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeDuplicateKeyTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeDuplicateKeyTest.java
index 71e2a38..b261e8a 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeDuplicateKeyTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeDuplicateKeyTest.java
@@ -35,6 +35,7 @@
 import org.apache.commons.io.FileUtils;
 import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
 import org.apache.directory.mavibot.btree.exception.DuplicateValueNotAllowedException;
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.IntSerializer;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
@@ -72,7 +73,7 @@
         try
         {
             // Create a new BTree
-            btree = recordManager1.addBTree( "test", new LongSerializer(), new StringSerializer(),
+            btree = recordManager1.addBTree( "test", LongSerializer.INSTANCE, StringSerializer.INSTANCE,
                 BTree.ALLOW_DUPLICATES );
         }
         catch ( Exception e )
@@ -122,7 +123,7 @@
 
 
     @Test
-    public void testInsertNullValue() throws IOException
+    public void testInsertNullValue() throws IOException, KeyNotFoundException
     {
         btree.insert( 1L, null );
 
@@ -141,11 +142,14 @@
 
 
     @Test
-    public void testBrowseEmptyTree() throws IOException
+    public void testBrowseEmptyTree() throws IOException, KeyNotFoundException, BTreeAlreadyManagedException
     {
-        IntSerializer serializer = new IntSerializer();
+        IntSerializer serializer = IntSerializer.INSTANCE;
 
         BTree<Integer, Integer> btree = BTreeFactory.createPersistedBTree( "master", serializer, serializer );
+        
+        // Inject the newly created BTree into teh recordManager
+        recordManager1.manage( btree );
 
         TupleCursor<Integer, Integer> cursor = btree.browse();
         assertFalse( cursor.hasNext() );
@@ -177,7 +181,7 @@
 
 
     @Test
-    public void testDuplicateKey() throws IOException
+    public void testDuplicateKey() throws IOException, KeyNotFoundException
     {
         btree.insert( 1L, "1" );
         btree.insert( 1L, "2" );
@@ -792,8 +796,8 @@
     @Test(expected = DuplicateValueNotAllowedException.class)
     public void testBTreeForbidDups() throws IOException, BTreeAlreadyManagedException
     {
-        BTree<Long, String> singleValueBtree = recordManager1.addBTree( "test2", new LongSerializer(),
-            new StringSerializer(), BTree.FORBID_DUPLICATES );
+        BTree<Long, String> singleValueBtree = recordManager1.addBTree( "test2", LongSerializer.INSTANCE,
+            StringSerializer.INSTANCE, BTree.FORBID_DUPLICATES );
 
         for ( long i = 0; i < 64; i++ )
         {
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeTransactionTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeTransactionTest.java
index 706545f..aa91342 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeTransactionTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeTransactionTest.java
@@ -59,8 +59,8 @@
         try
         {
             // Create a new BTree with transaction and another one without
-            btreeWithTransactions = recordManagerTxn.addBTree( "testWithTxn", new LongSerializer(), new StringSerializer(), false );
-            btreeNoTransactions = recordManagerNoTxn.addBTree( "testNoTxn", new LongSerializer(), new StringSerializer(), false );
+            btreeWithTransactions = recordManagerTxn.addBTree( "testWithTxn", LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
+            btreeNoTransactions = recordManagerNoTxn.addBTree( "testNoTxn", LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
         }
         catch ( Exception e )
         {
@@ -130,9 +130,9 @@
         for ( long i = 0L; i < 1000L; i++ )
         {
             System.out.println( i );
-            btreeWithTransactions.beginTransaction();
+            //btreeWithTransactions.beginTransaction();
             btreeWithTransactions.insert( i, Long.toString( i ) );
-            btreeWithTransactions.commit();
+            //btreeWithTransactions.commit();
         }
 
         long t1 = System.currentTimeMillis();
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedStoreTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedStoreTest.java
index 9a57731..47f8057 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedStoreTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedStoreTest.java
@@ -325,15 +325,15 @@
         storeMethod.setAccessible( true );
 
         // Allocate some Pages
-        PageIO[] pageIos = new PageIO[4];
+        PageIO[] pageIos = new PageIO[3];
         pageIos[0] = new PageIO();
         pageIos[0].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
         pageIos[1] = new PageIO();
         pageIos[1].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
         pageIos[2] = new PageIO();
         pageIos[2].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
-        pageIos[3] = new PageIO();
-        pageIos[3].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
+//        pageIos[3] = new PageIO();
+//        pageIos[3].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
 
         // We start with 4 bytes
         byte[] bytes = new byte[]
@@ -396,10 +396,10 @@
         }
 
         // Write the bytes over 2 pages
-        position = ( Long ) storeMethod.invoke( recordManager, 15L, bytes, pageIos );
+        position = ( Long ) storeMethod.invoke( recordManager, 47L, bytes, pageIos );
 
-        assertEquals( 35, position );
-        pos = 27;
+        assertEquals( 67, position );
+        pos = 59;
         // The byte length
         assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
         assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
@@ -418,25 +418,25 @@
         }
 
         // Write the bytes over 4 pages
-        bytes = new byte[80];
+        bytes = new byte[112];
 
-        for ( int i = 0; i < 80; i++ )
+        for ( int i = 0; i < 112; i++ )
         {
             bytes[i] = ( byte ) ( i + 1 );
         }
 
         position = ( Long ) storeMethod.invoke( recordManager, 2L, bytes, pageIos );
 
-        assertEquals( 86, position );
+        assertEquals( 118, position );
         pos = 14;
         // The byte length
         assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
         assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
         assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
-        assertEquals( 0x50, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x70, pageIos[0].getData().get( pos++ ) );
 
         // The data in the first page
-        for ( int i = 0; i < 14; i++ )
+        for ( int i = 0; i < 46; i++ )
         {
             assertEquals( ( byte ) ( i + 1 ), pageIos[0].getData().get( pos++ ) );
         }
@@ -444,7 +444,7 @@
         // The data in the second page
         pos = 8;
 
-        for ( int i = 14; i < 38; i++ )
+        for ( int i = 46; i < 102; i++ )
         {
             assertEquals( ( byte ) ( i + 1 ), pageIos[1].getData().get( pos++ ) );
         }
@@ -452,19 +452,11 @@
         // The data in the third page
         pos = 8;
 
-        for ( int i = 38; i < 62; i++ )
+        for ( int i = 102; i < 112; i++ )
         {
             assertEquals( ( byte ) ( i + 1 ), pageIos[2].getData().get( pos++ ) );
         }
 
-        // The data in the forth page
-        pos = 8;
-
-        for ( int i = 62; i < 80; i++ )
-        {
-            assertEquals( ( byte ) ( i + 1 ), pageIos[3].getData().get( pos++ ) );
-        }
-
         recordManager.close();
     }
 }
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerFreePageTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerFreePageTest.java
index 4c808e8..8a41deb 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerFreePageTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerFreePageTest.java
@@ -28,11 +28,8 @@
 import java.util.Set;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.directory.mavibot.btree.BTree;
-import org.apache.directory.mavibot.btree.RecordManager;
-import org.apache.directory.mavibot.btree.Tuple;
-import org.apache.directory.mavibot.btree.TupleCursor;
 import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
 import org.junit.After;
@@ -42,7 +39,7 @@
 
 /**
  * test the RecordManager's free page management
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class RecordManagerFreePageTest
@@ -71,7 +68,7 @@
         try
         {
             // Create a new BTree
-            btree = recordManager1.addBTree( "test", new LongSerializer(), new StringSerializer(), false );
+            btree = recordManager1.addBTree( "test", LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
         }
         catch ( Exception e )
         {
@@ -120,14 +117,14 @@
         }
     }
 
-    private int nbElems = 100000;
+    private int nbElems = 10000;
 
 
     /**
-     * Test the creation of a RecordManager, and that we can read it back.  
+     * Test the creation of a RecordManager, and that we can read it back.
      */
     @Test
-    public void testRecordManager() throws IOException, BTreeAlreadyManagedException
+    public void testRecordManager() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
     {
         assertEquals( 1, recordManager1.getNbManagedTrees() );
 
@@ -144,6 +141,7 @@
 
         for ( int i = 0; i < nbElems; i++ )
         {
+            // System.out.println( i );
             Long key = ( long ) i;
             String value = Long.toString( key );
 
@@ -178,7 +176,7 @@
             units = "KB";
         }
 
-        System.out.println( size + units );
+        // System.out.println( size + units );
 
         openRecordManagerAndBtree();
 
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerPrivateMethodTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerPrivateMethodTest.java
index 6f15b9b..da9f579 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerPrivateMethodTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerPrivateMethodTest.java
@@ -28,9 +28,6 @@
 import java.lang.reflect.Method;
 import java.util.UUID;
 
-import org.apache.directory.mavibot.btree.BTree;
-import org.apache.directory.mavibot.btree.PageIO;
-import org.apache.directory.mavibot.btree.RecordManager;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
 import org.junit.After;
@@ -42,7 +39,7 @@
 
 /**
  * Test some of the RecordManager prvate methods
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class RecordManagerPrivateMethodTest
@@ -62,11 +59,13 @@
     {
         dataDir = tempFolder.newFolder( UUID.randomUUID().toString() );
 
+        System.out.println( dataDir + "/mavibot.db" );
+
         // Now, try to reload the file back
         recordManager = new RecordManager( dataDir.getAbsolutePath(), 32 );
 
         // Create a new BTree
-        btree = recordManager.addBTree( "test", new LongSerializer(), new StringSerializer(), false );
+        btree = recordManager.addBTree( "test", LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
     }
 
 
@@ -91,19 +90,19 @@
 
         assertEquals( 0, pages.length );
 
-        for ( int i = 1; i < 20; i++ )
+        for ( int i = 1; i <= 52; i++ )
         {
             pages = ( org.apache.directory.mavibot.btree.PageIO[] ) getFreePageIOsMethod.invoke( recordManager, i );
             assertEquals( 1, pages.length );
         }
 
-        for ( int i = 21; i < 44; i++ )
+        for ( int i = 53; i <= 108; i++ )
         {
             pages = ( org.apache.directory.mavibot.btree.PageIO[] ) getFreePageIOsMethod.invoke( recordManager, i );
             assertEquals( 2, pages.length );
         }
 
-        for ( int i = 45; i < 68; i++ )
+        for ( int i = 109; i <= 164; i++ )
         {
             pages = ( org.apache.directory.mavibot.btree.PageIO[] ) getFreePageIOsMethod.invoke( recordManager, i );
             assertEquals( 3, pages.length );
@@ -125,17 +124,17 @@
 
         assertEquals( 0, ( ( Integer ) computeNbPagesMethod.invoke( recordManager, 0 ) ).intValue() );
 
-        for ( int i = 1; i < 21; i++ )
+        for ( int i = 1; i < 53; i++ )
         {
             assertEquals( 1, ( ( Integer ) computeNbPagesMethod.invoke( recordManager, i ) ).intValue() );
         }
 
-        for ( int i = 21; i < 45; i++ )
+        for ( int i = 53; i < 109; i++ )
         {
             assertEquals( 2, ( ( Integer ) computeNbPagesMethod.invoke( recordManager, i ) ).intValue() );
         }
 
-        for ( int i = 45; i < 68; i++ )
+        for ( int i = 109; i < 164; i++ )
         {
             assertEquals( 3, ( ( Integer ) computeNbPagesMethod.invoke( recordManager, i ) ).intValue() );
         }
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java
index e5a52c6..dac72ec 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java
@@ -35,11 +35,6 @@
 import java.util.UUID;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.directory.mavibot.btree.BTree;
-import org.apache.directory.mavibot.btree.RecordManager;
-import org.apache.directory.mavibot.btree.Tuple;
-import org.apache.directory.mavibot.btree.TupleCursor;
-import org.apache.directory.mavibot.btree.ValueCursor;
 import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
@@ -54,7 +49,7 @@
 
 /**
  * test the RecordManager
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class RecordManagerTest
@@ -74,12 +69,14 @@
     {
         dataDir = tempFolder.newFolder( UUID.randomUUID().toString() );
 
+        System.out.println( dataDir + "/mavibot.db" );
+
         openRecordManagerAndBtree();
 
         try
         {
             // Create a new BTree
-            btree = recordManager.addBTree( "test", new LongSerializer(), new StringSerializer(), false );
+            btree = recordManager.addBTree( "test", LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
         }
         catch ( Exception e )
         {
@@ -126,7 +123,7 @@
 
 
     /**
-     * Test the creation of a RecordManager, and that we can read it back.  
+     * Test the creation of a RecordManager, and that we can read it back.
      */
     @Test
     public void testRecordManager() throws IOException, BTreeAlreadyManagedException
@@ -397,7 +394,7 @@
 
 
     /**
-     * Test the creation of a RecordManager with a BTree containing data, where we keep the revisions, 
+     * Test the creation of a RecordManager with a BTree containing data, where we keep the revisions,
      * and browse the BTree.
      */
     @Test
@@ -457,10 +454,10 @@
 
         // Check that we can read the revision again
         // revision 1
-        checkBTreeRevisionBrowse( btree, rev1, 3L );
+        checkBTreeRevisionBrowse( btree, rev1 );
 
         // Revision 2
-        checkBTreeRevisionBrowse( btree, rev2, 1L, 3L );
+        checkBTreeRevisionBrowse( btree, rev2 );
 
         // Revision 3
         checkBTreeRevisionBrowse( btree, rev3, 1L, 3L, 5L );
@@ -468,7 +465,7 @@
 
 
     /**
-     * Test the creation of a RecordManager with a BTree containing data, where we keep the revision, and 
+     * Test the creation of a RecordManager with a BTree containing data, where we keep the revision, and
      * we browse from a key
      */
     @Test
@@ -528,10 +525,10 @@
 
         // Check that we can read the revision again
         // revision 1
-        checkBTreeRevisionBrowseFrom( btree, rev1, 3L, 3L );
+        checkBTreeRevisionBrowseFrom( btree, rev1, 3L );
 
         // Revision 2
-        checkBTreeRevisionBrowseFrom( btree, rev2, 3L, 3L );
+        checkBTreeRevisionBrowseFrom( btree, rev2, 3L );
 
         // Revision 3
         checkBTreeRevisionBrowseFrom( btree, rev3, 3L, 3L, 5L );
@@ -618,20 +615,16 @@
 
         // Check that we can get a value from each revision
         // revision 1
-        assertEquals( "V3", btree.get( rev1, 3L ) );
+        checkBTreeRevisionBrowse( btree, rev1 );
 
         // revision 2
-        assertEquals( "V1", btree.get( rev2, 1L ) );
-        assertEquals( "V3", btree.get( rev2, 3L ) );
+        checkBTreeRevisionBrowse( btree, rev2 );
 
         // revision 3
-        assertEquals( "V1", btree.get( rev3, 1L ) );
-        assertEquals( "V3", btree.get( rev3, 3L ) );
-        assertEquals( "V5", btree.get( rev3, 5L ) );
+        checkBTreeRevisionBrowse( btree, rev3 );
 
         // revision 4
-        assertEquals( "V1", btree.get( rev4, 1L ) );
-        assertEquals( "V5", btree.get( rev4, 5L ) );
+        checkBTreeRevisionBrowse( btree, rev4, 1L, 5L );
 
         try
         {
@@ -720,18 +713,18 @@
         // Check that we can get a value from each revision
         // revision 1
         assertFalse( btree.contains( rev1, 1L, "V1" ) );
-        assertTrue( btree.contains( rev1, 3L, "V3" ) );
+        assertFalse( btree.contains( rev1, 3L, "V3" ) );
         assertFalse( btree.contains( rev1, 5L, "V5" ) );
 
         // revision 2
-        assertTrue( btree.contains( rev2, 1L, "V1" ) );
-        assertTrue( btree.contains( rev2, 3L, "V3" ) );
+        assertFalse( btree.contains( rev2, 1L, "V1" ) );
+        assertFalse( btree.contains( rev2, 3L, "V3" ) );
         assertFalse( btree.contains( rev2, 5L, "V5" ) );
 
         // revision 3
-        assertTrue( btree.contains( rev3, 1L, "V1" ) );
-        assertTrue( btree.contains( rev3, 3L, "V3" ) );
-        assertTrue( btree.contains( rev3, 5L, "V5" ) );
+        assertFalse( btree.contains( rev3, 1L, "V1" ) );
+        assertFalse( btree.contains( rev3, 3L, "V3" ) );
+        assertFalse( btree.contains( rev3, 5L, "V5" ) );
 
         // revision 4
         assertTrue( btree.contains( rev4, 1L, "V1" ) );
@@ -815,18 +808,18 @@
         // Check that we can get a value from each revision
         // revision 1
         assertFalse( btree.hasKey( rev1, 1L ) );
-        assertTrue( btree.hasKey( rev1, 3L ) );
+        assertFalse( btree.hasKey( rev1, 3L ) );
         assertFalse( btree.hasKey( rev1, 5L ) );
 
         // revision 2
-        assertTrue( btree.hasKey( rev2, 1L ) );
-        assertTrue( btree.hasKey( rev2, 3L ) );
+        assertFalse( btree.hasKey( rev2, 1L ) );
+        assertFalse( btree.hasKey( rev2, 3L ) );
         assertFalse( btree.hasKey( rev2, 5L ) );
 
         // revision 3
-        assertTrue( btree.hasKey( rev3, 1L ) );
-        assertTrue( btree.hasKey( rev3, 3L ) );
-        assertTrue( btree.hasKey( rev3, 5L ) );
+        assertFalse( btree.hasKey( rev3, 1L ) );
+        assertFalse( btree.hasKey( rev3, 3L ) );
+        assertFalse( btree.hasKey( rev3, 5L ) );
 
         // revision 4
         assertTrue( btree.hasKey( rev4, 1L ) );
@@ -848,8 +841,8 @@
         String[] testValues = new String[]
             { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10" };
 
-        BTree<Long, String> dupsTree = BTreeFactory.createPersistedBTree( name, new LongSerializer(),
-            new StringSerializer(), pageSize, true );
+        BTree<Long, String> dupsTree = BTreeFactory.createPersistedBTree( name, LongSerializer.INSTANCE,
+            StringSerializer.INSTANCE, pageSize, true );
 
         recordManager.manage( dupsTree );
 
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerWithDuplicatesTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerWithDuplicatesTest.java
index 1599601..a59b3a7 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerWithDuplicatesTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerWithDuplicatesTest.java
@@ -30,8 +30,6 @@
 import java.util.UUID;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.directory.mavibot.btree.BTree;
-import org.apache.directory.mavibot.btree.RecordManager;
 import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
@@ -45,7 +43,7 @@
 
 /**
  * test the RecordManager whith duplicate values
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class RecordManagerWithDuplicatesTest
@@ -70,7 +68,7 @@
         try
         {
             // Create a new BTree which allows duplicate values
-            btree = recordManager.addBTree( "test", new LongSerializer(), new StringSerializer(), true );
+            btree = recordManager.addBTree( "test", LongSerializer.INSTANCE, StringSerializer.INSTANCE, true );
         }
         catch ( Exception e )
         {
@@ -114,7 +112,7 @@
 
 
     /**
-     * Test the creation of a RecordManager, and that we can read it back.  
+     * Test the creation of a RecordManager, and that we can read it back.
      */
     @Test
     public void testRecordManager() throws IOException, BTreeAlreadyManagedException
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RevisionNameComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RevisionNameComparatorTest.java
index 81a1160..8491a61 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RevisionNameComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RevisionNameComparatorTest.java
@@ -22,14 +22,12 @@
 
 import static org.junit.Assert.assertEquals;
 
-import org.apache.directory.mavibot.btree.RevisionName;
-import org.apache.directory.mavibot.btree.RevisionNameComparator;
 import org.junit.Test;
 
 
 /**
  * Test the RevisionNameComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class RevisionNameComparatorTest
@@ -37,7 +35,7 @@
     @Test
     public void testRevisionNameComparator()
     {
-        RevisionNameComparator comparator = new RevisionNameComparator();
+        RevisionNameComparator comparator = RevisionNameComparator.INSTANCE;
 
         assertEquals( 0, comparator.compare( null, null ) );
         assertEquals( 0, comparator.compare( new RevisionName( 0L, "test" ), new RevisionName( 0L, "test" ) ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RevisionNameSerializerTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RevisionNameSerializerTest.java
index a23ec56..30ce23b 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/RevisionNameSerializerTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/RevisionNameSerializerTest.java
@@ -26,8 +26,6 @@
 
 import java.io.IOException;
 
-import org.apache.directory.mavibot.btree.RevisionName;
-import org.apache.directory.mavibot.btree.RevisionNameSerializer;
 import org.apache.directory.mavibot.btree.serializer.BufferHandler;
 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
@@ -36,12 +34,12 @@
 
 /**
  * Test the RevisionNameSerializer class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class RevisionNameSerializerTest
 {
-    private static RevisionNameSerializer serializer = new RevisionNameSerializer();
+    private static RevisionNameSerializer serializer = RevisionNameSerializer.INSTANCE;
 
 
     @Test
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/BooleanArrayComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/BooleanArrayComparatorTest.java
index 5fe5493..709ae15 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/BooleanArrayComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/BooleanArrayComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the BooleanArrayComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class BooleanArrayComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testBooleanArrayComparator()
     {
-        BooleanArrayComparator comparator = new BooleanArrayComparator();
+        BooleanArrayComparator comparator = BooleanArrayComparator.INSTANCE;
 
         assertEquals( 0, comparator.compare( null, null ) );
 
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/BooleanComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/BooleanComparatorTest.java
index 6b34fe8..e2daf9c 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/BooleanComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/BooleanComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the BooleanComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class BooleanComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testBooleanComparator()
     {
-        BooleanComparator comparator = new BooleanComparator();
+        BooleanComparator comparator = BooleanComparator.INSTANCE;
 
         assertEquals( 0, comparator.compare( null, null ) );
         assertEquals( 0, comparator.compare( true, true ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ByteArrayComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ByteArrayComparatorTest.java
index 261d367..9a256d0 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ByteArrayComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ByteArrayComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the ByteArrayComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class ByteArrayComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testByteArrayComparator()
     {
-        ByteArrayComparator comparator = new ByteArrayComparator();
+        ByteArrayComparator comparator = ByteArrayComparator.INSTANCE;
 
         // Check equality
         assertEquals( 0, comparator.compare( null, null ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ByteComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ByteComparatorTest.java
index 07f5098..b72c5e9 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ByteComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ByteComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the ByteComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class ByteComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testByteComparator()
     {
-        ByteComparator comparator = new ByteComparator();
+        ByteComparator comparator = ByteComparator.INSTANCE;
 
         assertEquals( 0, comparator.compare( null, null ) );
         assertEquals( 0, comparator.compare( ( byte ) 0x00, ( byte ) 0x00 ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/CharArrayComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/CharArrayComparatorTest.java
index 6bbda18..288bb58 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/CharArrayComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/CharArrayComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the CharArrayComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class CharArrayComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testCharArrayComparator()
     {
-        CharArrayComparator comparator = new CharArrayComparator();
+        CharArrayComparator comparator = CharArrayComparator.INSTANCE;
 
         // Check equality
         assertEquals( 0, comparator.compare( null, null ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/CharComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/CharComparatorTest.java
index 7312370..ec84861 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/CharComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/CharComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the CharComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class CharComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testCharComparator()
     {
-        CharComparator comparator = new CharComparator();
+        CharComparator comparator = CharComparator.INSTANCE;
 
         assertEquals( 0, comparator.compare( null, null ) );
         assertEquals( 0, comparator.compare( 'a', 'a' ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/IntArrayComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/IntArrayComparatorTest.java
index 8feb043..1e88ee0 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/IntArrayComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/IntArrayComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the IntArrayComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class IntArrayComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testIntArrayComparator()
     {
-        IntArrayComparator comparator = new IntArrayComparator();
+        IntArrayComparator comparator = IntArrayComparator.INSTANCE;
 
         // Check equality
         assertEquals( 0, comparator.compare( null, null ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/IntComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/IntComparatorTest.java
index a27ca1d..27c9cf0 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/IntComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/IntComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the IntComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class IntComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testIntComparator()
     {
-        IntComparator comparator = new IntComparator();
+        IntComparator comparator = IntComparator.INSTANCE;
 
         assertEquals( 0, comparator.compare( null, null ) );
         assertEquals( 0, comparator.compare( 1, 1 ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/LongArrayComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/LongArrayComparatorTest.java
index 4832508..b2de9ac 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/LongArrayComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/LongArrayComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the LongArrayComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class LongArrayComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testLongArrayComparator()
     {
-        LongArrayComparator comparator = new LongArrayComparator();
+        LongArrayComparator comparator = LongArrayComparator.INSTANCE;
 
         // Check equality
         assertEquals( 0, comparator.compare( null, null ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/LongComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/LongComparatorTest.java
index 327e5aa..ad3a59b 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/LongComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/LongComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the LongComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class LongComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testLongComparator()
     {
-        LongComparator comparator = new LongComparator();
+        LongComparator comparator = LongComparator.INSTANCE;
 
         assertEquals( 0, comparator.compare( null, null ) );
         assertEquals( 0, comparator.compare( 1L, 1L ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ShortArrayComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ShortArrayComparatorTest.java
index 6832a50..bc53670 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ShortArrayComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ShortArrayComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the ShortArrayComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class ShortArrayComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testShortArrayComparator()
     {
-        ShortArrayComparator comparator = new ShortArrayComparator();
+        ShortArrayComparator comparator = ShortArrayComparator.INSTANCE;
 
         // Check equality
         assertEquals( 0, comparator.compare( null, null ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ShortComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ShortComparatorTest.java
index 5a6cac2..4844f4a 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ShortComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/ShortComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the ShortComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class ShortComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testShortComparator()
     {
-        ShortComparator comparator = new ShortComparator();
+        ShortComparator comparator = ShortComparator.INSTANCE;
 
         assertEquals( 0, comparator.compare( null, null ) );
         assertEquals( 0, comparator.compare( ( short ) 1, ( short ) 1 ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/StringComparatorTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/StringComparatorTest.java
index 5018c6e..21fe3dc 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/StringComparatorTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/comparator/StringComparatorTest.java
@@ -27,7 +27,7 @@
 
 /**
  * Test the StringComparator class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class StringComparatorTest
@@ -35,7 +35,7 @@
     @Test
     public void testStringComparator()
     {
-        StringComparator comparator = new StringComparator();
+        StringComparator comparator = StringComparator.INSTANCE;
 
         assertEquals( 0, comparator.compare( null, null ) );
         assertEquals( 0, comparator.compare( "", "" ) );
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/BooleanSerializerTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/BooleanSerializerTest.java
index f4ba67a..37417c9 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/BooleanSerializerTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/BooleanSerializerTest.java
@@ -29,12 +29,12 @@
 
 /**
  * Test the BooleanSerializer class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class BooleanSerializerTest
 {
-    private static BooleanSerializer serializer = new BooleanSerializer();
+    private static BooleanSerializer serializer = BooleanSerializer.INSTANCE;
 
 
     @Test
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ByteArraySerializerTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ByteArraySerializerTest.java
index 427583b..9c8ccf0 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ByteArraySerializerTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ByteArraySerializerTest.java
@@ -31,12 +31,12 @@
 
 /**
  * Test the BytesSerializer class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class ByteArraySerializerTest
 {
-    private static ByteArraySerializer serializer = new ByteArraySerializer();
+    private static ByteArraySerializer serializer = ByteArraySerializer.INSTANCE;
 
 
     @Test
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ByteSerializerTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ByteSerializerTest.java
index e99c8d5..5c9adff 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ByteSerializerTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ByteSerializerTest.java
@@ -29,12 +29,12 @@
 
 /**
  * Test the ByteSerializer class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class ByteSerializerTest
 {
-    private static ByteSerializer serializer = new ByteSerializer();
+    private static ByteSerializer serializer = ByteSerializer.INSTANCE;
 
 
     @Test
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/CharSerializerTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/CharSerializerTest.java
index eb6d6b7..abd588a 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/CharSerializerTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/CharSerializerTest.java
@@ -29,12 +29,12 @@
 
 /**
  * Test the CharSerializer class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class CharSerializerTest
 {
-    private static CharSerializer serializer = new CharSerializer();
+    private static CharSerializer serializer = CharSerializer.INSTANCE;
 
 
     @Test
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/IntSerializerTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/IntSerializerTest.java
index f852ffe..0b11aaf 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/IntSerializerTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/IntSerializerTest.java
@@ -29,12 +29,12 @@
 
 /**
  * Test the IntSerializer class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class IntSerializerTest
 {
-    private static IntSerializer serializer = new IntSerializer();
+    private static IntSerializer serializer = IntSerializer.INSTANCE;
 
 
     @Test
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/LongArraySerializerTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/LongArraySerializerTest.java
new file mode 100644
index 0000000..fe45b39
--- /dev/null
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/LongArraySerializerTest.java
@@ -0,0 +1,129 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree.serializer;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+
+/**
+ * Test the LongArraySerializer class
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class LongArraySerializerTest
+{
+    LongArraySerializer longArraySerializer = LongArraySerializer.INSTANCE;
+    
+    @Test
+    @Ignore
+    public void testLongArraySerializer() throws IOException
+    {
+        long[] value = null;
+        byte[] result = longArraySerializer.serialize( value );
+        int pos = 0;
+
+        assertEquals( 4, result.length );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+
+        assertEquals( value, longArraySerializer.deserialize( new BufferHandler( result ) ) );
+
+        // ------------------------------------------------------------------
+        value = new long[]{};
+        result = longArraySerializer.serialize( value );
+        pos = 0;
+
+        assertEquals( 4, result.length );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+
+        assertTrue( Arrays.equals( value, longArraySerializer.deserialize( new BufferHandler( result ) ) ) );
+
+        // ------------------------------------------------------------------
+        value = new long[]{ 1L };
+        result = longArraySerializer.serialize( value );
+        pos = 0;
+
+        assertEquals( 12, result.length );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x01, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x01, result[pos++] );
+
+        assertTrue( Arrays.equals( value, longArraySerializer.deserialize( new BufferHandler( result ) ) ) );
+        
+        // ------------------------------------------------------------------
+        value = new long[]{ 1L, 0x00000000FFFFFFFFL, 0xFFFFFFFFFFFFFFFFL };
+        result = longArraySerializer.serialize( value );
+        pos = 0;
+
+        assertEquals( 28, result.length );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x03, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x01, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0x00, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+        assertEquals( ( byte ) 0xFF, result[pos++] );
+
+        assertTrue( Arrays.equals( value, longArraySerializer.deserialize( new BufferHandler( result ) ) ) );
+    }
+}
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/LongSerializerTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/LongSerializerTest.java
index 269f6b8..856920d 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/LongSerializerTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/LongSerializerTest.java
@@ -29,14 +29,11 @@
 
 /**
  * Test the LongSerializer class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class LongSerializerTest
 {
-    private static LongSerializer serializer = new LongSerializer();
-
-
     @Test
     public void testLongSerializer() throws IOException
     {
@@ -52,7 +49,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x0000000000000001L;
@@ -67,7 +64,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x00000000000000FFL;
@@ -82,7 +79,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x0000000000000100L;
@@ -97,7 +94,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x000000000000FFFFL;
@@ -112,7 +109,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x0000000000010000L;
@@ -127,7 +124,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x0000000000FFFFFFL;
@@ -142,7 +139,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x0000000001000000L;
@@ -157,7 +154,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x000000007FFFFFFFL;
@@ -172,7 +169,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x0000000080000000L;
@@ -187,7 +184,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x00000000FFFFFFFFL;
@@ -202,7 +199,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x0000000100000000L;
@@ -217,7 +214,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x000000FFFFFFFFFFL;
@@ -232,7 +229,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x0000010000000000L;
@@ -247,7 +244,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x0000FFFFFFFFFFFFL;
@@ -262,7 +259,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x0001000000000000L;
@@ -277,7 +274,7 @@
         assertEquals( ( byte ) 0x01, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x00FFFFFFFFFFFFFFL;
@@ -292,7 +289,7 @@
         assertEquals( ( byte ) 0xFF, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x0100000000000000L;
@@ -307,7 +304,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x01, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x7FFFFFFFFFFFFFFFL;
@@ -322,7 +319,7 @@
         assertEquals( ( byte ) 0xFF, result[1] );
         assertEquals( ( byte ) 0x7F, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0x8000000000000000L;
@@ -337,7 +334,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x80, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
 
         // ------------------------------------------------------------------
         value = 0xFFFFFFFFFFFFFFFFL;
@@ -352,6 +349,6 @@
         assertEquals( ( byte ) 0xFF, result[1] );
         assertEquals( ( byte ) 0xFF, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).longValue() );
+        assertEquals( value, LongSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).longValue() );
     }
 }
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ShortSerializerTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ShortSerializerTest.java
index 255ca42..0ad6050 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ShortSerializerTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/ShortSerializerTest.java
@@ -29,14 +29,11 @@
 
 /**
  * Test the ShortSerializer class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class ShortSerializerTest
 {
-    private static ShortSerializer serializer = new ShortSerializer();
-
-
     @Test
     public void testShortSerializer() throws IOException
     {
@@ -46,7 +43,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).shortValue() );
+        assertEquals( value, ShortSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).shortValue() );
 
         // ------------------------------------------------------------------
         value = 0x0001;
@@ -55,7 +52,7 @@
         assertEquals( ( byte ) 0x01, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).shortValue() );
+        assertEquals( value, ShortSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).shortValue() );
 
         // ------------------------------------------------------------------
         value = 0x00FF;
@@ -64,7 +61,7 @@
         assertEquals( ( byte ) 0xFF, result[1] );
         assertEquals( ( byte ) 0x00, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).shortValue() );
+        assertEquals( value, ShortSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).shortValue() );
 
         // ------------------------------------------------------------------
         value = 0x0100;
@@ -73,7 +70,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x01, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).shortValue() );
+        assertEquals( value, ShortSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).shortValue() );
 
         // ------------------------------------------------------------------
         value = 0x7FFF;
@@ -82,7 +79,7 @@
         assertEquals( ( byte ) 0xFF, result[1] );
         assertEquals( ( byte ) 0x7F, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).shortValue() );
+        assertEquals( value, ShortSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).shortValue() );
 
         // ------------------------------------------------------------------
         value = ( short ) 0x8000;
@@ -91,7 +88,7 @@
         assertEquals( ( byte ) 0x00, result[1] );
         assertEquals( ( byte ) 0x80, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).shortValue() );
+        assertEquals( value, ShortSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).shortValue() );
 
         // ------------------------------------------------------------------
         value = ( short ) 0xFFFF;
@@ -100,6 +97,6 @@
         assertEquals( ( byte ) 0xFF, result[1] );
         assertEquals( ( byte ) 0xFF, result[0] );
 
-        assertEquals( value, serializer.deserialize( new BufferHandler( result ) ).shortValue() );
+        assertEquals( value, ShortSerializer.INSTANCE.deserialize( new BufferHandler( result ) ).shortValue() );
     }
 }
diff --git a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/StringSerializerTest.java b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/StringSerializerTest.java
index d3e6ce3..a76bd52 100644
--- a/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/StringSerializerTest.java
+++ b/mavibot/src/test/java/org/apache/directory/mavibot/btree/serializer/StringSerializerTest.java
@@ -29,12 +29,12 @@
 
 /**
  * Test the StringSerializer class
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class StringSerializerTest
 {
-    private static StringSerializer serializer = new StringSerializer();
+    private static StringSerializer serializer = StringSerializer.INSTANCE;
 
 
     @Test
diff --git a/mavibot/src/test/resources/log4j.properties b/mavibot/src/test/resources/log4j.properties
index b20ba58..c6e0497 100644
--- a/mavibot/src/test/resources/log4j.properties
+++ b/mavibot/src/test/resources/log4j.properties
@@ -14,11 +14,11 @@
 #    See the License for the specific language governing permissions and
 #    limitations under the License.
 #############################################################################
-log4j.rootCategory=OFF, stdout
+log4j.rootCategory=DEBUG, stdout
 
 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %p [%c-%X{Replica}] - %m%n
+log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %p [%c] - %m%n
 #log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %p [%c-%X{Replica}] %C{1}.%M@%L - %m%n
 
 log4j.appender.file=org.apache.log4j.RollingFileAppender
@@ -30,3 +30,6 @@
 
 #log4j.logger.org=FATAL
 log4j.logger.org.apache.directory.mavibot.btree=ERROR
+log4j.logger.LOG_PAGES=ERROR
+log4j.logger.LOG_CHECK=ERROR
+log4j.logger.net.sf.ehcache.Cache=ERROR