public boolean insertMessage(Message message) throws SQLException {

    // threat null case
    //
    if (message == null) return false;

    // check if message exists
    //
    if (this.loadMessage(message.getUrl()) != null) {
      return false;
    }

    // make sure the message can be inserted
    //
    if (message.getUser() == null)
      throw new IllegalArgumentException("Message's user cannot be null when inserting");
    if (message.getMessageThread() == null)
      throw new IllegalArgumentException("Message's thread cannot be null when inserting");

    //
    // persist the words
    //
    this.insertWords(this.getRegularWords(message.getFormattedContent()));

    //
    // persist the message
    //
    String query =
        "insert into Message(threadID,userID,publishDate,content,formatted_content,url,parentID) values(?,?,?,?,?,?,?);";
    PreparedStatement statement =
        connection.prepareStatement(query, PreparedStatement.RETURN_GENERATED_KEYS);

    statement.setInt(1, message.getMessageThread().getId());
    statement.setInt(2, message.getUser().getId());
    statement.setString(3, message.getPublishDate());
    statement.setString(4, message.getContent());
    statement.setString(5, message.getFormattedContent());
    statement.setString(6, message.getUrl());
    if (message.getParent() != null) {
      Message msg = this.loadMessage(message.getParent().getUrl());
      if (msg != null) statement.setInt(7, msg.getId());
      else statement.setInt(7, -1);
    } else statement.setInt(7, -1);

    statement.execute();
    ResultSet set = statement.getGeneratedKeys();

    if (!set.next()) {
      System.out.println("!! Failed to read auto generated keys !!");
    } else {
      message.setId(set.getInt(1));
    }

    set.close();
    statement.close();

    System.out.println("Inserted a new message:");
    System.out.println("\t> url     : " + message.getUrl());
    // System.out.println ("\t> date    : " + message.getPublishDate());
    // System.out.println ("\t> content : " + message.getFormattedContent());

    // this.calculateMessageProperties(message.getId());
    return true;
  }