/*
   * Reads the database model given by the reader.
   *
   * @param reader The reader that returns the model XML
   *
   * @return The database model
   */
  public static Database read(Reader reader, boolean validate) {
    try {
      boolean done = false;
      Database database = null;

      XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
      parser.setInput(reader);

      int eventType = parser.getEventType();
      while (eventType != XmlPullParser.END_DOCUMENT && !done) {
        switch (eventType) {
          case XmlPullParser.START_DOCUMENT:
            database = new Database();
            break;
          case XmlPullParser.START_TAG:
            String name = parser.getName();
            if (name.equalsIgnoreCase("database")) {
              for (int i = 0; i < parser.getAttributeCount(); i++) {
                String attributeName = parser.getAttributeName(i);
                String attributeValue = parser.getAttributeValue(i);
                if (attributeName.equalsIgnoreCase("name")) {
                  database.setName(attributeValue);
                } else if (attributeName.equalsIgnoreCase("catalog")) {
                  database.setCatalog(attributeValue);
                } else if (attributeName.equalsIgnoreCase("schema")) {
                  database.setSchema(attributeValue);
                }
              }
            } else if (name.equalsIgnoreCase("table")) {
              Table table = nextTable(parser, database.getCatalog(), database.getSchema());
              if (table != null) {
                database.addTable(table);
              }
            }
            break;
          case XmlPullParser.END_TAG:
            name = parser.getName();
            if (name.equalsIgnoreCase("database")) {
              done = true;
            }
            break;
        }
        eventType = parser.next();
      }

      if (validate) {
        database.initialize();
      }
      return database;
    } catch (XmlPullParserException e) {
      throw new IoException(e);
    } catch (IOException e) {
      throw new IoException(e);
    }
  }