gt:     protected static void closeAll() {
context: /*
   * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
   * Version 1.0, and under the Eclipse Public License, Version 1.0
   * (http://h2database.com/html/license.html).
   * Initial Developer: H2 Group
   */
  package org.h2.fulltext;
  
  import java.sql.Connection;
  import java.sql.PreparedStatement;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  import java.sql.Statement;
  import java.util.HashMap;
  import java.util.HashSet;
  import org.h2.util.New;
  import org.h2.util.SoftHashMap;
  
  /**
   * The global settings of a full text search.
   */
  public class FullTextSettings {
  
      /**
       * The settings of open indexes.
       */
      protected static final HashMap<String, FullTextSettings> SETTINGS = New.hashMap();
  
      /**
       * Whether this instance has been initialized.
       */
      protected boolean initialized;
  
      /**
       * The set of words not to index (stop words).
       */
      protected HashSet<String> ignoreList = New.hashSet();
  
      /**
       * The set of words / terms.
       */
      protected HashMap<String, Integer> words = New.hashMap();
  
      /**
       * The set of indexes in this database.
       */
      protected HashMap<Integer, IndexInfo> indexes = New.hashMap();
  
      /**
       * The prepared statement cache.
       */
      protected SoftHashMap<Connection, SoftHashMap<String, PreparedStatement>> cache =
          new SoftHashMap<Connection, SoftHashMap<String, PreparedStatement>>();
  
      /**
       * The whitespace characters.
       */
      protected String whitespaceChars = " \t\n\r\f+\"*%&/()=?'!,.;:-_#@|^~`{}[]<>\\";
  
      /**
       * Create a new instance.
       */
      protected FullTextSettings() {
          // don't allow construction
      }
  
      /**
       * Get the ignore list.
       *
       * @return the ignore list
       */
      protected HashSet<String> getIgnoreList() {
          return ignoreList;
      }
  
      /**
       * Get the word list.
       *
       * @return the word list
       */
      protected HashMap<String, Integer> getWordList() {
          return words;
      }
  
      /**
       * Get the index information for the given index id.
       *
       * @param indexId the index id
       * @return the index info
       */
      protected IndexInfo getIndexInfo(int indexId) {
          return indexes.get(indexId);
      }
  
      /**
       * Add an index.
       *
       * @param index the index
       */
      protected void addIndexInfo(IndexInfo index) {
          indexes.put(index.id, index);
      }
  
      /**
       * Convert a word to uppercase. This method returns null if the word is in
       * the ignore list.
       *
       * @param word the word to convert and check
       * @return the uppercase version of the word or null
       */
      protected String convertWord(String word) {
          // TODO this is locale specific, document
          word = word.toUpperCase();
          if (ignoreList.contains(word)) {
              return null;
          }
          return word;
      }
  
      /**
       * Get or create the fulltext settings for this database.
       *
       * @param conn the connection
       * @return the settings
       */
      protected static FullTextSettings getInstance(Connection conn) throws SQLException {
          String path = getIndexPath(conn);
          FullTextSettings setting = SETTINGS.get(path);
          if (setting == null) {
              setting = new FullTextSettings();
              SETTINGS.put(path, setting);
          }
          return setting;
      }
  
      /**
       * Get the file system path.
       *
       * @param conn the connection
       * @return the file system path
       */
      protected static String getIndexPath(Connection conn) throws SQLException {
          Statement stat = conn.createStatement();
          ResultSet rs = stat.executeQuery("CALL IFNULL(DATABASE_PATH(), 'MEM:' || DATABASE())");
          rs.next();
          String path = rs.getString(1);
          if ("MEM:UNNAMED".equals(path)) {
              throw FullText.throwException("Fulltext search for private (unnamed) in-memory databases is not supported.");
          }
          rs.close();
          return path;
      }
  
      /**
       * Prepare a statement. The statement is cached in a soft reference cache.
       *
       * @param conn the connection
       * @param sql the statement
       * @return the prepared statement
       */
      protected synchronized PreparedStatement prepare(Connection conn, String sql) throws SQLException {
          SoftHashMap<String, PreparedStatement> c = cache.get(conn);
          if (c == null) {
              c = new SoftHashMap<String, PreparedStatement>();
              cache.put(conn, c);
          }
          PreparedStatement prep = c.get(sql);
          if (prep != null && prep.getConnection().isClosed()) {
              prep = null;
          }
          if (prep == null) {
              prep = conn.prepareStatement(sql);
              c.put(sql, prep);
          }
          return prep;
      }
  
      /**
       * Remove all indexes from the settings.
       */
      protected void removeAllIndexes() {
          indexes.clear();
      }
  
      /**
       * Remove an index from the settings.
       *
       * @param index the index to remove
       */
      protected void removeIndexInfo(IndexInfo index) {
          indexes.remove(index.id);
      }
  
      /**
       * Set the initialized flag.
       *
       * @param b the new value
       */
      protected void setInitialized(boolean b) {
          this.initialized = b;
      }
  
      /**
       * Get the initialized flag.
       *
       * @return whether this instance is initialized
       */
      protected boolean isInitialized() {
          return initialized;
      }
  
      /**
       * Close all fulltext settings, freeing up memory.
       */
  