@SuppressWarnings("unchecked")
  @Override
  public void multiPut(List<List<Object>> keys, List<T> values) {
    LOG.debug("Putting the following keys: {} with values: {}", keys, values);
    try {
      List<Statement> statements = new ArrayList<Statement>();

      // Retrieve the mapping statement for the key,val pair
      for (int i = 0; i < keys.size(); i++) {
        List<Object> key = keys.get(i);
        T val = values.get(i);
        Statement retrievedStatment = mapper.map(key, val);
        if (retrievedStatment
            instanceof BatchStatement) { // Allows for BatchStatements to be returned by the mapper.
          BatchStatement batchedStatment = (BatchStatement) retrievedStatment;
          statements.addAll(batchedStatment.getStatements());
        } else {
          statements.add(retrievedStatment);
        }
      }

      // Execute all the statements as a batch.
      BatchStatement batch = new BatchStatement(batchType);
      batch.addAll(statements);
      session.execute(batch);

      _mwrites.incrBy(statements.size());
    } catch (Exception e) {
      checkCassandraException(e);
      LOG.error("Exception {} caught.", e);
    }
  }
 protected void checkCassandraException(Exception e) {
   _mexceptions.incr();
   if (e instanceof AlreadyExistsException
       || e instanceof AuthenticationException
       || e instanceof DriverException
       || e instanceof DriverInternalError
       || e instanceof InvalidConfigurationInQueryException
       || e instanceof InvalidQueryException
       || e instanceof InvalidTypeException
       || e instanceof QueryExecutionException
       || e instanceof QueryTimeoutException
       || e instanceof QueryValidationException
       || e instanceof ReadTimeoutException
       || e instanceof SyntaxError
       || e instanceof TraceRetrievalException
       || e instanceof TruncateException
       || e instanceof UnauthorizedException
       || e instanceof UnavailableException
       || e instanceof ReadTimeoutException
       || e instanceof WriteTimeoutException) {
     throw new ReportedFailedException(e);
   } else {
     throw new RuntimeException(e);
   }
 }
  ////////////////////////////////////
  // Overridden Methods for IBackingMap
  ////////////////////////////////////
  @SuppressWarnings("unchecked")
  @Override
  public List<T> multiGet(List<List<Object>> keys) {
    try {
      List<T> values = new ArrayList<T>();

      for (List<Object> rowKey : keys) {
        Statement statement = mapper.retrieve(rowKey);
        ResultSet results = session.execute(statement);
        // TODO: Better way to check for empty results besides accessing entire results list
        Iterator<Row> rowIter = results.iterator();
        Row row;
        if (results != null && rowIter.hasNext() && (row = rowIter.next()) != null) {
          if (rowIter.hasNext()) {
            LOG.error("Found non-unique value for key [{}]", rowKey);
          } else {
            values.add((T) mapper.getValue(row));
          }
        } else {
          values.add(null);
        }
      }

      _mreads.incrBy(values.size());
      LOG.debug("Retrieving the following keys: {} with values: {}", keys, values);
      return values;
    } catch (Exception e) {
      checkCassandraException(e);
      throw new IllegalStateException("Impossible to reach this code");
    }
  }