private boolean readLine() throws IOException {
    String attributeLine = null;
    do {
      attributeLine = inAttributes.readLine();
      if (attributeLine == null) return false;
    } while (attributeLine.startsWith("#") || (attributeLine.length() == 0));

    this.currentDataRow = getFactory().create(dimension);

    StringTokenizer tokenizer = new StringTokenizer(attributeLine);

    String labelString = null;
    if (format == FORMAT_YX) {
      labelString = tokenizer.nextToken();
    } else if (format == FORMAT_SEPARATE_FILE) {
      do {
        labelString = inLabels.readLine();
        if (labelString == null) return false;
      } while (labelString.startsWith("#") || (labelString.length() == 0));
    }

    while (tokenizer.hasMoreTokens()) {
      String attributeToken = tokenizer.nextToken();

      int colonIndex = attributeToken.indexOf(':');
      if ((format == FORMAT_XY) && (colonIndex == -1)) {
        if (labelString != null) {
          throw new IOException("Malformed line in examplefile: " + attributeToken);
        } else {
          labelString = attributeToken;
        }
      } else {
        String pos = attributeToken.substring(0, colonIndex); // references
        // the
        // attribute
        String value = attributeToken.substring(colonIndex + 1); // the
        // attribute
        // value
        Attribute attribute = null; // the referenced attribute

        try {
          int index = Integer.parseInt(pos) - 1;
          if ((index < 0) || (index >= attributeSet.getNumberOfRegularAttributes()))
            throw new IOException(
                "Attribute index out of range: '"
                    + (index + 1)
                    + "'! Index must be between 1 and dimension "
                    + attributeSet.getNumberOfRegularAttributes()
                    + "!");
          attribute = attributeSet.getAttribute(index);
        } catch (NumberFormatException e) {
          String specialAttributeName = prefixMap.get(pos);
          if (specialAttributeName == null) {
            attribute = attributeSet.getSpecialAttribute(pos);
            if (attribute == null)
              throw new IOException(
                  "Illegal attribute index: '"
                      + pos
                      + "' (legal values are integers and defined prefixes for special attributes (Parameter prefix_map of SparseFormatExampleSource))!");

          } else {
            attribute = attributeSet.getSpecialAttribute(specialAttributeName);
          }
          if (attribute == null)
            throw new IOException("Unknown special attribute: " + specialAttributeName);
        }

        if (attribute != null) {
          if (attribute.isNominal()) {
            if (useQuotesForNominalValues) {
              String quote = Character.toString(quoteChar);
              if (value.startsWith(quote) && value.endsWith(quote)) {
                value = value.substring(1, value.length() - 1);
              } else {
                throw new RuntimeException(
                    "The value ' "
                        + value
                        + " ' does not start and end with a quote character ' "
                        + quote
                        + " '.");
              }
              Tools.unescape(value);
            }
            currentDataRow.set(attribute, attribute.getMapping().mapString(value));
          } else {
            try {
              currentDataRow.set(attribute, Double.parseDouble(value));
            } catch (NumberFormatException e) {
              throw new IOException("Attribute is not numerical: '" + value + "'!");
            }
          }
        }
      }
    }

    if (labelString != null) {
      Attribute label = attributeSet.getSpecialAttribute("label");
      if (label.isNominal()) {
        currentDataRow.set(label, label.getMapping().mapString(labelString));
      } else {
        try {
          currentDataRow.set(label, Double.parseDouble(labelString));
        } catch (NumberFormatException e) {
          throw new IOException("Label is not numerical: '" + labelString + "'.");
        }
      }
    }

    currentDataRow.trim();
    return true;
  }