@Override
  public final void createOrUpdateUserAccount(final UserAccount userAccount) {

    if (userAccount == null) {
      throw new IllegalArgumentException("The passed user account was null.");
    }

    final Mutator mutator = connectionPool.createMutator();

    final String uuid = UUID.randomUUID().toString();
    final String username = userAccount.getUsername();
    final String password = userAccount.getPassword();

    // first we register the user user account under a new uuid
    mutator.writeColumns(
        COLUMN_FAMILY_USER,
        uuid,
        mutator.newColumnList(
            mutator.newColumn("username", username), mutator.newColumn("password", password)));

    // then we update the inverted index for the uuid
    mutator.writeColumns(
        COLUMN_FAMILY_USERNAME, username, mutator.newColumnList(mutator.newColumn("userid", uuid)));

    // finally commit both updates
    mutator.execute(CONSISTENCY_LEVEL_WRITE);

    userAccount.setId(uuid);
  }
  @Override
  public GatewayClient storeClient(GatewayClient client) throws DatastoreException {

    log.debug("Storing client: [%s]", client);
    Application application = getApplication(client.getBareJid());
    if (application == null) {
      log.debug("Client [%s] already exists", client);
      throw new ApplicationNotFoundException();
    }

    Mutator mutator = Pelops.createMutator(schemaName);
    mutator.writeColumns(
        "clients",
        client.getBareJid(),
        mutator.newColumnList(mutator.newColumn(client.getResource(), client.getResource())));
    try {
      mutator.execute(ConsistencyLevel.ONE);
      log.debug("Client [%s] stored successfully", client);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      throw new DatastoreException(
          String.format("Could not create client application [%s]", client));
    }

    return client;
  }
  private Application saveApplication(Application application) throws DatastoreException {

    Mutator mutator = Pelops.createMutator(schemaName);

    mutator.writeColumns(
        "applications",
        application.getBareJid(),
        mutator.newColumnList(
            mutator.newColumn(Bytes.fromUTF8("appId"), Bytes.fromUTF8(application.getAppId())),
            mutator.newColumn(
                Bytes.fromUTF8("platformId"), Bytes.fromUTF8(application.getPlatform())),
            mutator.newColumn(Bytes.fromUTF8("name"), Bytes.fromUTF8(application.getName())),
            mutator.newColumn(
                Bytes.fromUTF8("accountId"), Bytes.fromUTF8(application.getAccountId())),
            mutator.newColumn(
                Bytes.fromUTF8("permissions"), Bytes.fromUTF8(application.getPermissions()))));

    try {
      mutator.execute(ConsistencyLevel.ONE);
      log.debug("Application [%s] stored successfully", application);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      throw new DatastoreException(String.format("Could not create application [%s]", application));
    }

    return application;
  }
  private RayoNode store(RayoNode node) throws DatastoreException {

    Mutator mutator = Pelops.createMutator(schemaName);
    for (String platform : node.getPlatforms()) {
      mutator.writeSubColumns(
          "nodes",
          platform,
          node.getHostname(),
          mutator.newColumnList(
              mutator.newColumn("priority", String.valueOf(node.getPriority())),
              mutator.newColumn("weight", String.valueOf(node.getWeight())),
              mutator.newColumn("ip", node.getIpAddress()),
              mutator.newColumn("consecutive-errors", String.valueOf(node.getConsecutiveErrors())),
              mutator.newColumn("blacklisted", String.valueOf(node.isBlackListed()))));
    }

    mutator.writeColumn(
        "ips",
        Bytes.fromUTF8(node.getIpAddress()),
        mutator.newColumn(Bytes.fromUTF8("node"), Bytes.fromUTF8(node.getHostname())));

    try {
      mutator.execute(ConsistencyLevel.ONE);
      log.debug("Node [%s] stored successfully", node);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      throw new DatastoreException(String.format("Could not create node [%s]", node));
    }
    return node;
  }
  @Override
  public void addCallToMixer(String callId, String mixerName) throws DatastoreException {

    log.debug("Adding call [%s] to mixer [%s]", callId, mixerName);

    Mutator mutator = Pelops.createMutator(schemaName);
    mutator.writeColumns(
        "mixers",
        Bytes.fromUTF8(mixerName),
        mutator.newColumnList(mutator.newColumn(Bytes.fromUTF8(callId), Bytes.fromUTF8(callId))));

    try {
      mutator.execute(ConsistencyLevel.ONE);
      log.debug("Call [%s] added successfully to mixer [%s]", callId, mixerName);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      throw new DatastoreException("Could not add call to mixer");
    }
  }
  @Override
  public void createFilter(String jid, String id) throws DatastoreException {

    log.debug("Filering id [%s] for app [%s]", id, jid);

    Mutator mutator = Pelops.createMutator(schemaName);
    mutator.writeColumns(
        "filters",
        Bytes.fromUTF8(id),
        mutator.newColumnList(mutator.newColumn(Bytes.fromUTF8(jid), Bytes.fromUTF8(jid))));

    try {
      mutator.execute(ConsistencyLevel.ONE);
      log.debug("Id [%s] has been filtered for app [%s]", id, jid);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      throw new DatastoreException("Could not create new filter");
    }
  }
  @Override
  public void addVerbToMixer(GatewayVerb verb, String mixerName) throws DatastoreException {

    log.debug("Adding verb [%s] to mixer [%s]", verb.getVerbId(), mixerName);

    Mutator mutator = Pelops.createMutator(schemaName);
    mutator.writeColumns(
        "verbs",
        Bytes.fromUTF8(mixerName),
        mutator.newColumnList(
            mutator.newColumn(Bytes.fromUTF8(verb.getVerbId()), Bytes.fromUTF8(verb.getAppJid()))));

    try {
      mutator.execute(ConsistencyLevel.ONE);
      log.debug("Verb [%s] added successfully to mixer [%s]", verb.getVerbId(), mixerName);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      throw new DatastoreException("Could not add verb to mixer");
    }
  }
  @Override
  public GatewayMixer storeMixer(GatewayMixer mixer) throws DatastoreException {

    log.debug("Storing mixer: [%s]", mixer);

    Mutator mutator = Pelops.createMutator(schemaName);
    mutator.writeColumns(
        "mixers",
        Bytes.fromUTF8(mixer.getName()),
        mutator.newColumnList(
            mutator.newColumn(Bytes.fromUTF8("node"), Bytes.fromUTF8(mixer.getNodeJid()))));

    try {
      mutator.execute(ConsistencyLevel.ONE);
      log.debug("Mixer [%s] stored successfully", mixer);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      throw new DatastoreException("Could not store mixer");
    }

    return mixer;
  }
  @Override
  public GatewayCall storeCall(GatewayCall call) throws DatastoreException {

    log.debug("Storing call: [%s]", call);
    RayoNode node = getNode(call.getNodeJid());
    if (node == null) {
      log.debug("Node [%s] not found for call [%s]", call.getNodeJid(), call);
      throw new RayoNodeNotFoundException();
    }

    Mutator mutator = Pelops.createMutator(schemaName);
    mutator.writeColumns(
        "calls",
        Bytes.fromUTF8(call.getCallId()),
        mutator.newColumnList(
            mutator.newColumn(Bytes.fromUTF8("jid"), Bytes.fromUTF8(call.getClientJid())),
            mutator.newColumn(Bytes.fromUTF8("node"), Bytes.fromUTF8(call.getNodeJid()))));

    mutator.writeSubColumn(
        "jids",
        "clients",
        Bytes.fromUTF8(call.getClientJid()),
        mutator.newColumn(Bytes.fromUTF8(call.getCallId()), Bytes.fromUTF8(call.getCallId())));
    mutator.writeSubColumn(
        "jids",
        "nodes",
        Bytes.fromUTF8(call.getNodeJid()),
        mutator.newColumn(Bytes.fromUTF8(call.getCallId()), Bytes.fromUTF8(call.getCallId())));

    try {
      mutator.execute(ConsistencyLevel.ONE);
      log.debug("Call [%s] stored successfully", call);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      throw new DatastoreException("Could not store call");
    }

    return call;
  }