code: public void previsit(Collection<? extends IRenderingElement> elements) {
          Deque<IRenderingElement> queue = new ArrayDeque<>(2 * elements.size());
          queue.addAll(elements);
  
          FreqMap<Color> strokeFreq = new FreqMap<>();
          FreqMap<Color> fillFreq = new FreqMap<>();
          FreqMap<Double> strokeWidthFreq = new FreqMap<>();
  
          while (!queue.isEmpty()) {
              IRenderingElement element = queue.poll();
              // wrappers first
              if (element instanceof Bounds) {
                  queue.add(((Bounds) element).root());
              } else if (element instanceof MarkedElement) {
                  queue.add(((MarkedElement) element).element());
              } else if (element instanceof ElementGroup) {
                  for (IRenderingElement child : (ElementGroup) element)
                      queue.add(child);
              } else if (element instanceof LineElement) {
                  strokeFreq.add(((LineElement) element).color);
                  strokeWidthFreq.add(scaled(((LineElement) element).width));
              } else if (element instanceof GeneralPath) {
                  if (((GeneralPath) element).fill)
                      fillFreq.add(((GeneralPath) element).color);
              } else {
                  // ignored
              }
          }
  
          if (!defaultsWritten) {
              defaultFill = fillFreq.getMostFrequent();
              defaultStroke = strokeFreq.getMostFrequent();
              Double strokeWidth = strokeWidthFreq.getMostFrequent();
              if (strokeWidth != null)
                  defaultStrokeWidth = toStr(strokeWidth);
          }
      }
docs: Pre-visit allows us to prepare the visitor for more optimal output.
  Currently we
  - find the most common stoke/fill/stroke-width values and set these as defaults
  
  @param elements elements to be visited