diff --git a/dao/etc/dao.png b/dao/etc/dao.png
index 9fe34b976..452e72ba1 100644
Binary files a/dao/etc/dao.png and b/dao/etc/dao.png differ
diff --git a/dao/etc/dao.ucls b/dao/etc/dao.ucls
index bf11f18b3..0706837fc 100644
--- a/dao/etc/dao.ucls
+++ b/dao/etc/dao.ucls
@@ -1,45 +1,71 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <class-diagram version="1.1.8" icons="true" always-add-relationships="false" generalizations="true" realizations="true" 
   associations="true" dependencies="false" nesting-relationships="true">  
-  <class id="1" language="java" name="com.iluwatar.Customer" project="dao" 
-    file="/dao/src/main/java/com/iluwatar/Customer.java" binary="false" corner="BOTTOM_RIGHT">    
-    <position height="-1" width="-1" x="176" y="337"/>    
+  <class id="1" language="java" name="com.iluwatar.dao.App" project="dao" 
+    file="/dao/src/main/java/com/iluwatar/dao/App.java" binary="false" corner="BOTTOM_RIGHT">    
+    <position height="-1" width="-1" x="910" y="191"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
       sort-features="false" accessors="true" visibility="true">      
-      <attributes public="true" package="true" protected="true" private="true" static="true"/>      
-      <operations public="true" package="true" protected="true" private="true" static="true"/>    
+      <attributes public="true" package="true" protected="true" private="false" static="true"/>      
+      <operations public="true" package="true" protected="true" private="false" static="true"/>    
     </display>  
   </class>  
-  <class id="2" language="java" name="com.iluwatar.CustomerDaoImpl" project="dao" 
-    file="/dao/src/main/java/com/iluwatar/CustomerDaoImpl.java" binary="false" corner="BOTTOM_RIGHT">    
-    <position height="-1" width="-1" x="540" y="334"/>    
-    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
-      sort-features="false" accessors="true" visibility="true">      
-      <attributes public="true" package="true" protected="true" private="true" static="true"/>      
-      <operations public="true" package="true" protected="true" private="true" static="true"/>    
-    </display>  
-  </class>  
-  <interface id="3" language="java" name="com.iluwatar.CustomerDao" project="dao" 
-    file="/dao/src/main/java/com/iluwatar/CustomerDao.java" binary="false" corner="BOTTOM_RIGHT">    
-    <position height="-1" width="-1" x="536" y="131"/>    
+  <interface id="2" language="java" name="com.iluwatar.dao.CustomerDao" project="dao" 
+    file="/dao/src/main/java/com/iluwatar/dao/CustomerDao.java" binary="false" corner="BOTTOM_RIGHT">    
+    <position height="-1" width="-1" x="536" y="187"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
       sort-features="false" accessors="true" visibility="true">      
       <attributes public="true" package="true" protected="true" private="true" static="true"/>      
       <operations public="true" package="true" protected="true" private="true" static="true"/>    
     </display>  
   </interface>  
-  <realization id="4">    
-    <end type="SOURCE" refId="2"/>    
-    <end type="TARGET" refId="3"/>  
-  </realization>  
-  <association id="5">    
-    <end type="SOURCE" refId="2" navigable="false">      
-      <attribute id="6" name="customers"/>      
-      <multiplicity id="7" minimum="0" maximum="2147483647"/>    
+  <class id="3" language="java" name="com.iluwatar.dao.InMemoryCustomerDao" project="dao" 
+    file="/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java" binary="false" corner="BOTTOM_RIGHT">    
+    <position height="-1" width="-1" x="289" y="455"/>    
+    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
+      sort-features="false" accessors="true" visibility="true">      
+      <attributes public="true" package="true" protected="true" private="false" static="true"/>      
+      <operations public="true" package="true" protected="true" private="true" static="true"/>    
+    </display>  
+  </class>  
+  <class id="4" language="java" name="com.iluwatar.dao.DBCustomerDao" project="dao" 
+    file="/dao/src/main/java/com/iluwatar/dao/DBCustomerDao.java" binary="false" corner="BOTTOM_RIGHT">    
+    <position height="-1" width="-1" x="751" y="456"/>    
+    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
+      sort-features="false" accessors="true" visibility="true">      
+      <attributes public="true" package="true" protected="true" private="false" static="true"/>      
+      <operations public="true" package="true" protected="true" private="false" static="true"/>    
+    </display>  
+  </class>  
+  <interface id="5" language="java" name="javax.sql.DataSource" project="dao" 
+    file="/opt/Softwares/Eclipses/MARS/eclipse/jre/lib/rt.jar" binary="true" corner="BOTTOM_RIGHT">    
+    <position height="-1" width="-1" x="1083" y="459"/>    
+    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
+      sort-features="false" accessors="true" visibility="true">      
+      <attributes public="true" package="true" protected="true" private="true" static="true"/>      
+      <operations public="true" package="true" protected="true" private="true" static="true"/>    
+    </display>  
+  </interface>  
+  <association id="6">    
+    <end type="SOURCE" refId="4" navigable="false">      
+      <attribute id="7" name="dataSource"/>      
+      <multiplicity id="8" minimum="0" maximum="1"/>    
     </end>    
-    <end type="TARGET" refId="1" navigable="true"/>    
+    <end type="TARGET" refId="5" navigable="true"/>    
     <display labels="true" multiplicity="true"/>  
   </association>  
+  <realization id="9">    
+    <end type="SOURCE" refId="3"/>    
+    <end type="TARGET" refId="2"/>  
+  </realization>  
+  <dependency id="10">    
+    <end type="SOURCE" refId="1"/>    
+    <end type="TARGET" refId="2"/>  
+  </dependency>  
+  <realization id="11">    
+    <end type="SOURCE" refId="4"/>    
+    <end type="TARGET" refId="2"/>  
+  </realization>  
   <classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
     sort-features="false" accessors="true" visibility="true">    
     <attributes public="true" package="true" protected="true" private="true" static="true"/>    
diff --git a/dao/pom.xml b/dao/pom.xml
index 3b6fc7d1e..05ab2b22a 100644
--- a/dao/pom.xml
+++ b/dao/pom.xml
@@ -44,6 +44,18 @@
       <groupId>log4j</groupId>
       <artifactId>log4j</artifactId>
     </dependency>
+    <dependency>
+        <groupId>com.h2database</groupId>
+        <artifactId>h2</artifactId>
+      </dependency>
+    <dependency>
+      <groupId>de.bechte.junit</groupId>
+      <artifactId>junit-hierarchicalcontextrunner</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-core</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
diff --git a/dao/src/main/java/com/iluwatar/dao/App.java b/dao/src/main/java/com/iluwatar/dao/App.java
index 3fa4b34d5..a63289ae9 100644
--- a/dao/src/main/java/com/iluwatar/dao/App.java
+++ b/dao/src/main/java/com/iluwatar/dao/App.java
@@ -20,49 +20,101 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+
 package com.iluwatar.dao;
 
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Stream;
+
+import javax.sql.DataSource;
 
 import org.apache.log4j.Logger;
+import org.h2.jdbcx.JdbcDataSource;
 
 /**
- * 
  * Data Access Object (DAO) is an object that provides an abstract interface to some type of
  * database or other persistence mechanism. By mapping application calls to the persistence layer,
  * DAO provide some specific data operations without exposing details of the database. This
  * isolation supports the Single responsibility principle. It separates what data accesses the
  * application needs, in terms of domain-specific objects and data types (the public interface of
  * the DAO), from how these needs can be satisfied with a specific DBMS.
- * <p>
- * With the DAO pattern, we can use various method calls to retrieve/add/delete/update data without
- * directly interacting with the data. The below example demonstrates basic CRUD operations: select,
- * add, update, and delete.
+ *
+ * <p>With the DAO pattern, we can use various method calls to retrieve/add/delete/update data 
+ * without directly interacting with the data source. The below example demonstrates basic CRUD 
+ * operations: select, add, update, and delete.
+ * 
  * 
  */
 public class App {
-
+  private static final String DB_URL = "jdbc:h2:~/dao:customerdb";
   private static Logger log = Logger.getLogger(App.class);
-
+  
   /**
    * Program entry point.
    * 
    * @param args command line args.
+   * @throws Exception if any error occurs. 
    */
-  public static void main(final String[] args) {
-    final CustomerDao customerDao = new CustomerDaoImpl(generateSampleCustomers());
-    log.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
-    log.info("customerDao.getCusterById(2): " + customerDao.getCustomerById(2));
+  public static void main(final String[] args) throws Exception {
+    final CustomerDao inMemoryDao = new InMemoryCustomerDao();
+    performOperationsUsing(inMemoryDao);
+    
+    final DataSource dataSource = createDataSource();
+    createSchema(dataSource);
+    final CustomerDao dbDao = new DbCustomerDao(dataSource);
+    performOperationsUsing(dbDao);
+    deleteSchema(dataSource);
+  }
+
+  private static void deleteSchema(DataSource dataSource) throws SQLException {
+    try (Connection connection = dataSource.getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute(CustomerSchemaSql.DELETE_SCHEMA_SQL);
+    }
+  }
+
+  private static void createSchema(DataSource dataSource) throws SQLException {
+    try (Connection connection = dataSource.getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute(CustomerSchemaSql.CREATE_SCHEMA_SQL);
+    }
+  }
+
+  private static DataSource createDataSource() {
+    JdbcDataSource dataSource = new JdbcDataSource();
+    dataSource.setURL(DB_URL);
+    return dataSource;
+  }
+
+  private static void performOperationsUsing(final CustomerDao customerDao) throws Exception {
+    addCustomers(customerDao);
+    log.info("customerDao.getAllCustomers(): ");
+    try (Stream<Customer> customerStream = customerDao.getAll()) {
+      customerStream.forEach((customer) -> log.info(customer));
+    }
+    log.info("customerDao.getCustomerById(2): " + customerDao.getById(2));
     final Customer customer = new Customer(4, "Dan", "Danson");
-    customerDao.addCustomer(customer);
-    log.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
+    customerDao.add(customer);
+    log.info("customerDao.getAllCustomers(): " + customerDao.getAll());
     customer.setFirstName("Daniel");
     customer.setLastName("Danielson");
-    customerDao.updateCustomer(customer);
-    log.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
-    customerDao.deleteCustomer(customer);
-    log.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
+    customerDao.update(customer);
+    log.info("customerDao.getAllCustomers(): ");
+    try (Stream<Customer> customerStream = customerDao.getAll()) {
+      customerStream.forEach((cust) -> log.info(cust));
+    }
+    customerDao.delete(customer);
+    log.info("customerDao.getAllCustomers(): " + customerDao.getAll());
+  }
+
+  private static void addCustomers(CustomerDao customerDao) throws Exception {
+    for (Customer customer : generateSampleCustomers()) {
+      customerDao.add(customer);
+    }
   }
 
   /**
diff --git a/dao/src/main/java/com/iluwatar/dao/Customer.java b/dao/src/main/java/com/iluwatar/dao/Customer.java
index 6d10fb146..d6b512dd6 100644
--- a/dao/src/main/java/com/iluwatar/dao/Customer.java
+++ b/dao/src/main/java/com/iluwatar/dao/Customer.java
@@ -20,11 +20,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+
 package com.iluwatar.dao;
 
 /**
- * 
- * Customer
+ * A customer POJO that represents the data that will be read from the data source.
  *
  */
 public class Customer {
@@ -34,7 +34,7 @@ public class Customer {
   private String lastName;
 
   /**
-   * Constructor
+   * Creates an instance of customer.
    */
   public Customer(final int id, final String firstName, final String lastName) {
     this.id = id;
@@ -73,12 +73,12 @@ public class Customer {
   }
 
   @Override
-  public boolean equals(final Object o) {
+  public boolean equals(final Object that) {
     boolean isEqual = false;
-    if (this == o) {
+    if (this == that) {
       isEqual = true;
-    } else if (o != null && getClass() == o.getClass()) {
-      final Customer customer = (Customer) o;
+    } else if (that != null && getClass() == that.getClass()) {
+      final Customer customer = (Customer) that;
       if (getId() == customer.getId()) {
         isEqual = true;
       }
diff --git a/dao/src/main/java/com/iluwatar/dao/CustomerDao.java b/dao/src/main/java/com/iluwatar/dao/CustomerDao.java
index 26b4df47b..059a9e9f7 100644
--- a/dao/src/main/java/com/iluwatar/dao/CustomerDao.java
+++ b/dao/src/main/java/com/iluwatar/dao/CustomerDao.java
@@ -20,24 +20,62 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+
 package com.iluwatar.dao;
 
-import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
 
 /**
+ * In an application the Data Access Object (DAO) is a part of Data access layer. It is an object
+ * that provides an interface to some type of persistence mechanism. By mapping application calls
+ * to the persistence layer, DAO provides some specific data operations without exposing details 
+ * of the database. This isolation supports the Single responsibility principle. It separates what
+ * data accesses the application needs, in terms of domain-specific objects and data types 
+ * (the public interface of the DAO), from how these needs can be satisfied with a specific DBMS,
+ * database schema, etc.
  * 
- * CustomerDao
- *
+ * <p>Any change in the way data is stored and retrieved will not change the client code as the 
+ * client will be using interface and need not worry about exact source.
+ * 
+ * @see InMemoryCustomerDao
+ * @see DbCustomerDao
  */
 public interface CustomerDao {
 
-  List<Customer> getAllCustomers();
+  /**
+   * @return all the customers as a stream. The stream may be lazily or eagerly evaluated based 
+   *     on the implementation. The stream must be closed after use.
+   * @throws Exception if any error occurs.
+   */
+  Stream<Customer> getAll() throws Exception;
+  
+  /**
+   * @param id unique identifier of the customer.
+   * @return an optional with customer if a customer with unique identifier <code>id</code>
+   *     exists, empty optional otherwise.
+   * @throws Exception if any error occurs.
+   */
+  Optional<Customer> getById(int id) throws Exception;
 
-  Customer getCustomerById(int id);
+  /**
+   * @param customer the customer to be added.
+   * @return true if customer is successfully added, false if customer already exists.
+   * @throws Exception if any error occurs.
+   */
+  boolean add(Customer customer) throws Exception;
 
-  void addCustomer(Customer customer);
+  /**
+   * @param customer the customer to be updated.
+   * @return true if customer exists and is successfully updated, false otherwise.
+   * @throws Exception if any error occurs.
+   */
+  boolean update(Customer customer) throws Exception;
 
-  void updateCustomer(Customer customer);
-
-  void deleteCustomer(Customer customer);
+  /**
+   * @param customer the customer to be deleted.
+   * @return true if customer exists and is successfully deleted, false otherwise.
+   * @throws Exception if any error occurs.
+   */
+  boolean delete(Customer customer) throws Exception;
 }
diff --git a/dao/src/main/java/com/iluwatar/dao/CustomerDaoImpl.java b/dao/src/main/java/com/iluwatar/dao/CustomerDaoImpl.java
deleted file mode 100644
index 25d4149fa..000000000
--- a/dao/src/main/java/com/iluwatar/dao/CustomerDaoImpl.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2014 Ilkka Seppälä
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.iluwatar.dao;
-
-import java.util.List;
-
-/**
- * 
- * The data access object (DAO) is an object that provides an abstract interface to some type of
- * database or other persistence mechanism. By mapping application calls to the persistence layer,
- * DAO provide some specific data operations without exposing details of the database. This
- * isolation supports the Single responsibility principle. It separates what data accesses the
- * application needs, in terms of domain-specific objects and data types (the public interface of
- * the DAO), from how these needs can be satisfied with a specific DBMS, database schema, etc.
- * 
- */
-public class CustomerDaoImpl implements CustomerDao {
-
-  // Represents the DB structure for our example so we don't have to managed it ourselves
-  // Note: Normally this would be in the form of an actual database and not part of the Dao Impl.
-  private List<Customer> customers;
-
-  public CustomerDaoImpl(final List<Customer> customers) {
-    this.customers = customers;
-  }
-
-  @Override
-  public List<Customer> getAllCustomers() {
-    return customers;
-  }
-
-  @Override
-  public Customer getCustomerById(final int id) {
-    Customer customer = null;
-    for (final Customer cus : getAllCustomers()) {
-      if (cus.getId() == id) {
-        customer = cus;
-        break;
-      }
-    }
-    return customer;
-  }
-
-  @Override
-  public void addCustomer(final Customer customer) {
-    if (getCustomerById(customer.getId()) == null) {
-      customers.add(customer);
-    }
-  }
-
-
-  @Override
-  public void updateCustomer(final Customer customer) {
-    if (getAllCustomers().contains(customer)) {
-      final int index = getAllCustomers().indexOf(customer);
-      getAllCustomers().set(index, customer);
-    }
-  }
-
-  @Override
-  public void deleteCustomer(final Customer customer) {
-    getAllCustomers().remove(customer);
-  }
-}
diff --git a/dao/src/main/java/com/iluwatar/dao/CustomerSchemaSql.java b/dao/src/main/java/com/iluwatar/dao/CustomerSchemaSql.java
new file mode 100644
index 000000000..05707fa0e
--- /dev/null
+++ b/dao/src/main/java/com/iluwatar/dao/CustomerSchemaSql.java
@@ -0,0 +1,9 @@
+package com.iluwatar.dao;
+
+public interface CustomerSchemaSql {
+
+  String CREATE_SCHEMA_SQL = "CREATE TABLE CUSTOMERS (ID NUMBER, FNAME VARCHAR(100), " 
+      + "LNAME VARCHAR(100))";
+  
+  String DELETE_SCHEMA_SQL = "DROP TABLE CUSTOMERS";
+}
diff --git a/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java b/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java
new file mode 100644
index 000000000..622b5b1f0
--- /dev/null
+++ b/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java
@@ -0,0 +1,183 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.dao;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Optional;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import javax.sql.DataSource;
+
+/**
+ * An implementation of {@link CustomerDao} that persists customers in RDBMS. 
+ *
+ */
+public class DbCustomerDao implements CustomerDao {
+
+  private final DataSource dataSource;
+
+  /**
+   * Creates an instance of {@link DbCustomerDao} which uses provided <code>dataSource</code>
+   * to store and retrieve customer information.
+   * 
+   * @param dataSource a non-null dataSource.
+   */
+  public DbCustomerDao(DataSource dataSource) {
+    this.dataSource = dataSource;
+  }
+
+  /**
+   * @return a lazily populated stream of customers. Note the stream returned must be closed to 
+   *     free all the acquired resources. The stream keeps an open connection to the database till
+   *     it is complete or is closed manually.
+   */
+  @Override
+  public Stream<Customer> getAll() throws Exception {
+
+    Connection connection;
+    try {
+      connection = getConnection();
+      PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS");
+      ResultSet resultSet = statement.executeQuery();
+      return StreamSupport.stream(new Spliterators.AbstractSpliterator<Customer>(Long.MAX_VALUE, 
+          Spliterator.ORDERED) {
+
+        @Override
+        public boolean tryAdvance(Consumer<? super Customer> action) {
+          try {
+            if (!resultSet.next()) {
+              return false;
+            }
+            action.accept(createCustomer(resultSet));
+            return true;
+          } catch (SQLException e) {
+            throw new RuntimeException(e);
+          }
+        }
+      }, false).onClose(() -> mutedClose(connection));
+    } catch (SQLException e) {
+      throw new Exception(e.getMessage(), e);
+    }
+  }
+
+  private Connection getConnection() throws SQLException {
+    return dataSource.getConnection();
+  }
+
+  private void mutedClose(Connection connection) {
+    try {
+      connection.close();
+    } catch (SQLException e) {
+      e.printStackTrace();
+    }
+  }
+
+  private Customer createCustomer(ResultSet resultSet) throws SQLException {
+    return new Customer(resultSet.getInt("ID"), 
+        resultSet.getString("FNAME"), 
+        resultSet.getString("LNAME"));
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Optional<Customer> getById(int id) throws Exception {
+    try (Connection connection = getConnection();
+        PreparedStatement statement = 
+            connection.prepareStatement("SELECT * FROM CUSTOMERS WHERE ID = ?")) {
+
+      statement.setInt(1, id);
+      ResultSet resultSet = statement.executeQuery();
+      if (resultSet.next()) {
+        return Optional.of(createCustomer(resultSet));
+      } else {
+        return Optional.empty();
+      }
+    } catch (SQLException ex) {
+      throw new Exception(ex.getMessage(), ex);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean add(Customer customer) throws Exception {
+    if (getById(customer.getId()).isPresent()) {
+      return false;
+    }
+
+    try (Connection connection = getConnection();
+        PreparedStatement statement = 
+            connection.prepareStatement("INSERT INTO CUSTOMERS VALUES (?,?,?)")) {
+      statement.setInt(1, customer.getId());
+      statement.setString(2, customer.getFirstName());
+      statement.setString(3, customer.getLastName());
+      statement.execute();
+      return true;
+    } catch (SQLException ex) {
+      throw new Exception(ex.getMessage(), ex);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean update(Customer customer) throws Exception {
+    try (Connection connection = getConnection();
+        PreparedStatement statement = 
+            connection.prepareStatement("UPDATE CUSTOMERS SET FNAME = ?, LNAME = ? WHERE ID = ?")) {
+      statement.setString(1, customer.getFirstName());
+      statement.setString(2, customer.getLastName());
+      statement.setInt(3, customer.getId());
+      return statement.executeUpdate() > 0;
+    } catch (SQLException ex) {
+      throw new Exception(ex.getMessage(), ex);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean delete(Customer customer) throws Exception {
+    try (Connection connection = getConnection();
+        PreparedStatement statement = 
+            connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) {
+      statement.setInt(1, customer.getId());
+      return statement.executeUpdate() > 0;
+    } catch (SQLException ex) {
+      throw new Exception(ex.getMessage(), ex);
+    }
+  }
+}
diff --git a/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java b/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java
new file mode 100644
index 000000000..15c63d1de
--- /dev/null
+++ b/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java
@@ -0,0 +1,73 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.dao;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+/**
+ * An in memory implementation of {@link CustomerDao}, which stores the customers in JVM memory
+ * and data is lost when the application exits.
+ * <br/>
+ * This implementation is useful as temporary database or for testing.
+ */
+public class InMemoryCustomerDao implements CustomerDao {
+
+  private Map<Integer, Customer> idToCustomer = new HashMap<>();
+
+  /**
+   * An eagerly evaluated stream of customers stored in memory.
+   */
+  @Override
+  public Stream<Customer> getAll() {
+    return idToCustomer.values().stream();
+  }
+
+  @Override
+  public Optional<Customer> getById(final int id) {
+    return Optional.ofNullable(idToCustomer.get(id));
+  }
+
+  @Override
+  public boolean add(final Customer customer) {
+    if (getById(customer.getId()).isPresent()) {
+      return false;
+    }
+    
+    idToCustomer.put(customer.getId(), customer);
+    return true;
+  }
+
+  @Override
+  public boolean update(final Customer customer) {
+    return idToCustomer.replace(customer.getId(), customer) != null;
+  }
+
+  @Override
+  public boolean delete(final Customer customer) {
+    return idToCustomer.remove(customer.getId()) != null;
+  }
+}
diff --git a/dao/src/test/java/com/iluwatar/dao/AppTest.java b/dao/src/test/java/com/iluwatar/dao/AppTest.java
index b4caa54b4..169fc046e 100644
--- a/dao/src/test/java/com/iluwatar/dao/AppTest.java
+++ b/dao/src/test/java/com/iluwatar/dao/AppTest.java
@@ -20,18 +20,17 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+
 package com.iluwatar.dao;
 
 import org.junit.Test;
 
-import java.io.IOException;
-
 /**
  * Tests that DAO example runs without errors.
  */
 public class AppTest {
   @Test
-  public void test() throws IOException {
+  public void test() throws Exception {
     String[] args = {};
     App.main(args);
   }
diff --git a/dao/src/test/java/com/iluwatar/dao/CustomerDaoImplTest.java b/dao/src/test/java/com/iluwatar/dao/CustomerDaoImplTest.java
deleted file mode 100644
index f30740629..000000000
--- a/dao/src/test/java/com/iluwatar/dao/CustomerDaoImplTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2014 Ilkka Seppälä
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.iluwatar.dao;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class CustomerDaoImplTest {
-
-  private CustomerDaoImpl impl;
-  private List<Customer> customers;
-  private static final Customer CUSTOMER = new Customer(1, "Freddy", "Krueger");
-
-  @Before
-  public void setUp() {
-    customers = new ArrayList<>();
-    customers.add(CUSTOMER);
-    impl = new CustomerDaoImpl(customers);
-  }
-
-  @Test
-  public void deleteExistingCustomer() {
-    assertEquals(1, impl.getAllCustomers().size());
-    impl.deleteCustomer(CUSTOMER);
-    assertTrue(impl.getAllCustomers().isEmpty());
-  }
-
-  @Test
-  public void deleteNonExistingCustomer() {
-    final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
-    impl.deleteCustomer(nonExistingCustomer);
-    assertEquals(1, impl.getAllCustomers().size());
-  }
-
-  @Test
-  public void updateExistingCustomer() {
-    final String newFirstname = "Bernard";
-    final String newLastname = "Montgomery";
-    final Customer customer = new Customer(CUSTOMER.getId(), newFirstname, newLastname);
-    impl.updateCustomer(customer);
-    final Customer cust = impl.getCustomerById(CUSTOMER.getId());
-    assertEquals(newFirstname, cust.getFirstName());
-    assertEquals(newLastname, cust.getLastName());
-  }
-
-  @Test
-  public void updateNonExistingCustomer() {
-    final int nonExistingId = getNonExistingCustomerId();
-    final String newFirstname = "Douglas";
-    final String newLastname = "MacArthur";
-    final Customer customer = new Customer(nonExistingId, newFirstname, newLastname);
-    impl.updateCustomer(customer);
-    assertNull(impl.getCustomerById(nonExistingId));
-    final Customer existingCustomer = impl.getCustomerById(CUSTOMER.getId());
-    assertEquals(CUSTOMER.getFirstName(), existingCustomer.getFirstName());
-    assertEquals(CUSTOMER.getLastName(), existingCustomer.getLastName());
-  }
-
-  @Test
-  public void addCustomer() {
-    final Customer newCustomer = new Customer(3, "George", "Patton");
-    impl.addCustomer(newCustomer);
-    assertEquals(2, impl.getAllCustomers().size());
-  }
-
-  @Test
-  public void addAlreadyAddedCustomer() {
-    final Customer newCustomer = new Customer(3, "George", "Patton");
-    impl.addCustomer(newCustomer);
-    assertEquals(2, impl.getAllCustomers().size());
-    impl.addCustomer(newCustomer);
-    assertEquals(2, impl.getAllCustomers().size());
-  }
-
-  @Test
-  public void getExistinCustomerById() {
-    assertEquals(CUSTOMER, impl.getCustomerById(CUSTOMER.getId()));
-  }
-
-  @Test
-  public void getNonExistinCustomerById() {
-    final int nonExistingId = getNonExistingCustomerId();
-    assertNull(impl.getCustomerById(nonExistingId));
-  }
-
-  /**
-   * An arbitrary number which does not correspond to an active Customer id.
-   * 
-   * @return an int of a customer id which doesn't exist
-   */
-  private int getNonExistingCustomerId() {
-    return 999;
-  }
-}
diff --git a/dao/src/test/java/com/iluwatar/dao/CustomerTest.java b/dao/src/test/java/com/iluwatar/dao/CustomerTest.java
index 600b5ba3f..6a02fd6be 100644
--- a/dao/src/test/java/com/iluwatar/dao/CustomerTest.java
+++ b/dao/src/test/java/com/iluwatar/dao/CustomerTest.java
@@ -20,6 +20,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+
 package com.iluwatar.dao;
 
 import static org.junit.Assert.assertEquals;
diff --git a/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java b/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java
new file mode 100644
index 000000000..08e61ebe6
--- /dev/null
+++ b/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java
@@ -0,0 +1,247 @@
+package com.iluwatar.dao;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.stream.Stream;
+
+import javax.sql.DataSource;
+
+import org.h2.jdbcx.JdbcDataSource;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+import de.bechte.junit.runners.context.HierarchicalContextRunner;
+
+/**
+ * Tests {@link DbCustomerDao}.
+ */
+@RunWith(HierarchicalContextRunner.class)
+public class DbCustomerDaoTest {
+
+  private static final String DB_URL = "jdbc:h2:~/dao:customerdb";
+  private DbCustomerDao dao;
+  private Customer existingCustomer = new Customer(1, "Freddy", "Krueger");
+
+  /**
+   * Creates customers schema.
+   * @throws SQLException if there is any error while creating schema.
+   */
+  @Before
+  public void createSchema() throws SQLException {
+    try (Connection connection = DriverManager.getConnection(DB_URL);
+        Statement statement = connection.createStatement()) {
+      statement.execute(CustomerSchemaSql.CREATE_SCHEMA_SQL);
+    }
+  }
+
+  /**
+   * Represents the scenario where DB connectivity is present.
+   */
+  public class ConnectionSuccess {
+
+    /**
+     * Setup for connection success scenario.
+     * @throws Exception if any error occurs.
+     */
+    @Before
+    public void setUp() throws Exception {
+      JdbcDataSource dataSource = new JdbcDataSource();
+      dataSource.setURL(DB_URL);
+      dao = new DbCustomerDao(dataSource);
+      boolean result = dao.add(existingCustomer);
+      assertTrue(result);
+    }
+
+    /**
+     * Represents the scenario when DAO operations are being performed on a non existing customer.
+     */
+    public class NonExistingCustomer {
+
+      @Test
+      public void addingShouldResultInSuccess() throws Exception {
+        try (Stream<Customer> allCustomers = dao.getAll()) {
+          assumeTrue(allCustomers.count() == 1);
+        }
+
+        final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
+        boolean result = dao.add(nonExistingCustomer);
+        assertTrue(result);
+
+        assertCustomerCountIs(2);
+        assertEquals(nonExistingCustomer, dao.getById(nonExistingCustomer.getId()).get());
+      }
+
+      @Test
+      public void deletionShouldBeFailureAndNotAffectExistingCustomers() throws Exception {
+        final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
+        boolean result = dao.delete(nonExistingCustomer);
+
+        assertFalse(result);
+        assertCustomerCountIs(1);
+      }
+
+      @Test
+      public void updationShouldBeFailureAndNotAffectExistingCustomers() throws Exception {
+        final int nonExistingId = getNonExistingCustomerId();
+        final String newFirstname = "Douglas";
+        final String newLastname = "MacArthur";
+        final Customer customer = new Customer(nonExistingId, newFirstname, newLastname);
+        boolean result = dao.update(customer);
+
+        assertFalse(result);
+        assertFalse(dao.getById(nonExistingId).isPresent());
+      }
+
+      @Test
+      public void retrieveShouldReturnNoCustomer() throws Exception {
+        assertFalse(dao.getById(getNonExistingCustomerId()).isPresent());
+      }
+    }
+
+    /**
+     * Represents a scenario where DAO operations are being performed on an already existing
+     * customer.
+     *
+     */
+    public class ExistingCustomer {
+
+      @Test
+      public void addingShouldResultInFailureAndNotAffectExistingCustomers() throws Exception {
+        Customer existingCustomer = new Customer(1, "Freddy", "Krueger");
+
+        boolean result = dao.add(existingCustomer);
+
+        assertFalse(result);
+        assertCustomerCountIs(1);
+        assertEquals(existingCustomer, dao.getById(existingCustomer.getId()).get());
+      }
+
+      @Test
+      public void deletionShouldBeSuccessAndCustomerShouldBeNonAccessible() throws Exception {
+        boolean result = dao.delete(existingCustomer);
+
+        assertTrue(result);
+        assertCustomerCountIs(0);
+        assertFalse(dao.getById(existingCustomer.getId()).isPresent());
+      }
+
+      @Test
+      public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdatedInformation() throws Exception {
+        final String newFirstname = "Bernard";
+        final String newLastname = "Montgomery";
+        final Customer customer = new Customer(existingCustomer.getId(), newFirstname, newLastname);
+        boolean result = dao.update(customer);
+
+        assertTrue(result);
+
+        final Customer cust = dao.getById(existingCustomer.getId()).get();
+        assertEquals(newFirstname, cust.getFirstName());
+        assertEquals(newLastname, cust.getLastName());
+      }
+    }
+  }
+
+  /**
+   * Represents a scenario where DB connectivity is not present due to network issue, or
+   * DB service unavailable.
+   * 
+   */
+  public class ConnectivityIssue {
+    
+    private static final String EXCEPTION_CAUSE = "Connection not available";
+    @Rule public ExpectedException exception = ExpectedException.none();
+    
+    /**
+     * setup a connection failure scenario.
+     * @throws SQLException if any error occurs.
+     */
+    @Before
+    public void setUp() throws SQLException {
+      dao = new DbCustomerDao(mockedDatasource());
+      exception.expect(Exception.class);
+      exception.expectMessage(EXCEPTION_CAUSE);
+    }
+    
+    private DataSource mockedDatasource() throws SQLException {
+      DataSource mockedDataSource = mock(DataSource.class);
+      Connection mockedConnection = mock(Connection.class);
+      SQLException exception = new SQLException(EXCEPTION_CAUSE);
+      doThrow(exception).when(mockedConnection).prepareStatement(Mockito.anyString());
+      doReturn(mockedConnection).when(mockedDataSource).getConnection();
+      return mockedDataSource;
+    }
+
+    @Test
+    public void addingACustomerFailsWithExceptionAsFeedbackToClient() throws Exception {
+      dao.add(new Customer(2, "Bernard", "Montgomery"));
+    }
+    
+    @Test
+    public void deletingACustomerFailsWithExceptionAsFeedbackToTheClient() throws Exception {
+      dao.delete(existingCustomer);
+    }
+    
+    @Test
+    public void updatingACustomerFailsWithFeedbackToTheClient() throws Exception {
+      final String newFirstname = "Bernard";
+      final String newLastname = "Montgomery";
+      
+      dao.update(new Customer(existingCustomer.getId(), newFirstname, newLastname));
+    }
+    
+    @Test
+    public void retrievingACustomerByIdFailsWithExceptionAsFeedbackToClient() throws Exception {
+      dao.getById(existingCustomer.getId());
+    }
+    
+    @Test
+    public void retrievingAllCustomersFailsWithExceptionAsFeedbackToClient() throws Exception {
+      dao.getAll();
+    }
+
+  }
+
+  /**
+   * Delete customer schema for fresh setup per test.
+   * @throws SQLException if any error occurs.
+   */
+  @After
+  public void deleteSchema() throws SQLException {
+    try (Connection connection = DriverManager.getConnection(DB_URL);
+        Statement statement = connection.createStatement()) {
+      statement.execute(CustomerSchemaSql.DELETE_SCHEMA_SQL);
+    }
+  }
+
+  private void assertCustomerCountIs(int count) throws Exception {
+    try (Stream<Customer> allCustomers = dao.getAll()) {
+      assertTrue(allCustomers.count() == count);
+    }
+  }
+
+
+  /**
+   * An arbitrary number which does not correspond to an active Customer id.
+   * 
+   * @return an int of a customer id which doesn't exist
+   */
+  private int getNonExistingCustomerId() {
+    return 999;
+  }
+}
diff --git a/dao/src/test/java/com/iluwatar/dao/InMemoryCustomerDaoTest.java b/dao/src/test/java/com/iluwatar/dao/InMemoryCustomerDaoTest.java
new file mode 100644
index 000000000..65a087b9b
--- /dev/null
+++ b/dao/src/test/java/com/iluwatar/dao/InMemoryCustomerDaoTest.java
@@ -0,0 +1,164 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.dao;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import de.bechte.junit.runners.context.HierarchicalContextRunner;
+
+/**
+ * Tests {@link InMemoryCustomerDao}.
+ */
+@RunWith(HierarchicalContextRunner.class)
+public class InMemoryCustomerDaoTest {
+
+  private InMemoryCustomerDao dao;
+  private static final Customer CUSTOMER = new Customer(1, "Freddy", "Krueger");
+
+  @Before
+  public void setUp() {
+    dao = new InMemoryCustomerDao();
+    assertTrue(dao.add(CUSTOMER));
+  }
+
+  /**
+   * Represents the scenario when the DAO operations are being performed on a non existent 
+   * customer.  
+   */
+  public class NonExistingCustomer {
+
+    @Test
+    public void addingShouldResultInSuccess() throws Exception {
+      try (Stream<Customer> allCustomers = dao.getAll()) {
+        assumeTrue(allCustomers.count() == 1);
+      }
+
+      final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
+      boolean result = dao.add(nonExistingCustomer);
+      assertTrue(result);
+
+      assertCustomerCountIs(2);
+      assertEquals(nonExistingCustomer, dao.getById(nonExistingCustomer.getId()).get());
+    }
+
+    @Test
+    public void deletionShouldBeFailureAndNotAffectExistingCustomers() throws Exception {
+      final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
+      boolean result = dao.delete(nonExistingCustomer);
+
+      assertFalse(result);
+      assertCustomerCountIs(1);
+    }
+
+    @Test
+    public void updationShouldBeFailureAndNotAffectExistingCustomers() throws Exception {
+      final int nonExistingId = getNonExistingCustomerId();
+      final String newFirstname = "Douglas";
+      final String newLastname = "MacArthur";
+      final Customer customer = new Customer(nonExistingId, newFirstname, newLastname);
+      boolean result = dao.update(customer);
+
+      assertFalse(result);
+      assertFalse(dao.getById(nonExistingId).isPresent());
+    }
+
+    @Test
+    public void retrieveShouldReturnNoCustomer() throws Exception {
+      assertFalse(dao.getById(getNonExistingCustomerId()).isPresent());
+    }
+  }
+
+  /**
+   * Represents the scenario when the DAO operations are being performed on an already existing
+   * customer.
+   */
+  public class ExistingCustomer {
+
+    @Test
+    public void addingShouldResultInFailureAndNotAffectExistingCustomers() throws Exception {
+      boolean result = dao.add(CUSTOMER);
+
+      assertFalse(result);
+      assertCustomerCountIs(1);
+      assertEquals(CUSTOMER, dao.getById(CUSTOMER.getId()).get());
+    }
+
+    @Test
+    public void deletionShouldBeSuccessAndCustomerShouldBeNonAccessible() throws Exception {
+      boolean result = dao.delete(CUSTOMER);
+
+      assertTrue(result);
+      assertCustomerCountIs(0);
+      assertFalse(dao.getById(CUSTOMER.getId()).isPresent());
+    }
+
+    @Test
+    public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdatedInformation() throws Exception {
+      final String newFirstname = "Bernard";
+      final String newLastname = "Montgomery";
+      final Customer customer = new Customer(CUSTOMER.getId(), newFirstname, newLastname);
+      boolean result = dao.update(customer);
+
+      assertTrue(result);
+
+      final Customer cust = dao.getById(CUSTOMER.getId()).get();
+      assertEquals(newFirstname, cust.getFirstName());
+      assertEquals(newLastname, cust.getLastName());
+    }
+    
+    @Test
+    public void retriveShouldReturnTheCustomer() {
+      Optional<Customer> optionalCustomer = dao.getById(CUSTOMER.getId());
+      
+      assertTrue(optionalCustomer.isPresent());
+      assertEquals(CUSTOMER, optionalCustomer.get());
+    }
+  }
+
+  /**
+   * An arbitrary number which does not correspond to an active Customer id.
+   * 
+   * @return an int of a customer id which doesn't exist
+   */
+  private int getNonExistingCustomerId() {
+    return 999;
+  }
+  
+  private void assertCustomerCountIs(int count) throws Exception {
+    try (Stream<Customer> allCustomers = dao.getAll()) {
+      assertTrue(allCustomers.count() == count);
+    }
+  }
+}
diff --git a/pom.xml b/pom.xml
index 57d030756..9127a865a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,6 +50,7 @@
  		<guava.version>19.0</guava.version>
 		<systemrules.version>1.15.1</systemrules.version>
 		<mockito.version>1.10.19</mockito.version>
+		<hierarchical-junit-runner-version>4.12.1</hierarchical-junit-runner-version>
 	</properties>
 	<modules>
 		<module>abstract-factory</module>
@@ -196,6 +197,12 @@
 				<version>${systemrules.version}</version>
 				<scope>test</scope>
 			</dependency>
+			<dependency>
+				<groupId>de.bechte.junit</groupId>
+  				<artifactId>junit-hierarchicalcontextrunner</artifactId>
+  				<version>${hierarchical-junit-runner-version}</version>
+  				<scope>test</scope>
+			</dependency>
 		</dependencies>
 	</dependencyManagement>