/**
   * Updates the layout. It is designed to do a re-layout only, not to process input data again.
   *
   * @param root the root
   * @param newDimension the new dimension
   * @param cba the CSSBoxAnalyzer
   * @return the list
   * @throws IOException Signals that an I/O exception has occurred.
   */
  public List<ElementSpec> update(ElementBox root, Dimension newDimension, CSSBoxAnalyzer cba)
      throws IOException {
    if (cba == null)
      throw new IllegalArgumentException(
          "CSSBoxAnalyzer can not be NULL !!!\nProvide your custom implementation or check instantiation of DefaultAnalyzer object...");

    List<ElementSpec> elements = new LinkedList<ElementSpec>();
    elements.add(new ElementSpec(SimpleAttributeSet.EMPTY, ElementSpec.EndTagType));

    ElementBox tmp;
    try {
      tmp = cba.update(root, newDimension);
    } catch (Exception e) {
      throw new IOException(e);
    }

    if (tmp instanceof Viewport) {
      // tmp should by an instance of Viewport
      buildViewport(elements, (Viewport) tmp);
    } else {
      buildElements(elements, tmp);
    }

    return elements;
  }
  /**
   * Reads input data and converts them to "elements"
   *
   * @param is the input source
   * @param url the source of data
   * @param cba the instance of {@link CSSBoxAnalyzer}
   * @return the list of elements. Note that, this method returns instance of LinkedList.
   * @throws IOException Signals that an I/O exception has occurred.
   */
  public List<ElementSpec> read(DocumentSource docSource, CSSBoxAnalyzer cba, Dimension dim)
      throws IOException {
    // ale ked sa pouzije setText() neviem nic o url, nic sa nenastavuje ,
    // moze byt null
    // (URL) doc.getProperty(Document.StreamDescriptionProperty)

    if (cba == null)
      throw new IllegalArgumentException(
          "CSSBoxAnalyzer can not be NULL !!!\nProvide your custom implementation or check instantiation of DefaultAnalyzer object...");

    List<ElementSpec> elements = new LinkedList<ElementSpec>(); // ArrayList<ElementSpec>(1024);
    elements.add(new ElementSpec(SimpleAttributeSet.EMPTY, ElementSpec.EndTagType));

    // System.err.print("used Reader and encoding ? " +
    // is.getCharacterStream() + "  ,  ");
    // InputStreamReader r = (InputStreamReader)is.getCharacterStream();
    // System.err.println(r.getEncoding());

    ElementBox root;
    try {
      // System.err.println("analyzing...");
      root = cba.analyze(docSource, dim);
      // System.err.println("analyzing finished...");
    } catch (Exception e) {
      throw new IOException(e);
    }

    if (root instanceof Viewport) {
      // root should by an instance of Viewport
      buildViewport(elements, (Viewport) root);
    } else {
      buildElements(elements, root);
    }

    // System.err.println("num. of elements : " + elements.size());
    // System.err.println("Root min width : " + root.getMinimalWidth() +
    // " ,normal width : " + root.getWidth() + " ,maximal width : " +
    // root.getMaximalWidth());

    // TODO po skonceni nacitavania aj nejake info spravit
    // >> Document.TitleProperty - observer, metainfo
    return elements;
  }