/**
   * Constructs an {@code AttributedString} from an {@code AttributedCharacterIterator}, which
   * represents attributed text.
   *
   * @param iterator the {@code AttributedCharacterIterator} that contains the text for this
   *     attributed string.
   */
  public AttributedString(AttributedCharacterIterator iterator) {
    if (iterator.getBeginIndex() > iterator.getEndIndex()) {
      // text.0A=Invalid substring range
      throw new IllegalArgumentException(Messages.getString("text.0A")); // $NON-NLS-1$
    }
    StringBuilder buffer = new StringBuilder();
    for (int i = iterator.getBeginIndex(); i < iterator.getEndIndex(); i++) {
      buffer.append(iterator.current());
      iterator.next();
    }
    text = buffer.toString();
    Set<AttributedCharacterIterator.Attribute> attributes = iterator.getAllAttributeKeys();
    if (attributes == null) {
      return;
    }
    attributeMap = new HashMap<Attribute, List<Range>>((attributes.size() * 4 / 3) + 1);

    Iterator<Attribute> it = attributes.iterator();
    while (it.hasNext()) {
      AttributedCharacterIterator.Attribute attribute = it.next();
      iterator.setIndex(0);
      while (iterator.current() != CharacterIterator.DONE) {
        int start = iterator.getRunStart(attribute);
        int limit = iterator.getRunLimit(attribute);
        Object value = iterator.getAttribute(attribute);
        if (value != null) {
          addAttribute(attribute, value, start, limit);
        }
        iterator.setIndex(limit);
      }
    }
  }
 /**
  * Creates an {@code AttributedString} from the given text and the attributes. The whole text has
  * the given attributes applied.
  *
  * @param value the text to take as base for this attributed string.
  * @param attributes the attributes that the text is associated with.
  * @throws IllegalArgumentException if the length of {@code value} is 0 but the size of {@code
  *     attributes} is greater than 0.
  * @throws NullPointerException if {@code value} is {@code null}.
  */
 public AttributedString(
     String value, Map<? extends AttributedCharacterIterator.Attribute, ?> attributes) {
   if (value == null) {
     throw new NullPointerException();
   }
   if (value.length() == 0 && !attributes.isEmpty()) {
     // text.0B=Cannot add attributes to empty string
     throw new IllegalArgumentException(Messages.getString("text.0B")); // $NON-NLS-1$
   }
   text = value;
   attributeMap = new HashMap<Attribute, List<Range>>((attributes.size() * 4 / 3) + 1);
   Iterator<?> it = attributes.entrySet().iterator();
   while (it.hasNext()) {
     Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next();
     ArrayList<Range> ranges = new ArrayList<Range>(1);
     ranges.add(new Range(0, text.length(), entry.getValue()));
     attributeMap.put((AttributedCharacterIterator.Attribute) entry.getKey(), ranges);
   }
 }