docs: @Override
      public String decode( String encodedText ) {
          if (encodedText == null) return null;
          StringBuilder sb = new StringBuilder();
          CharacterIterator iter = new StringCharacterIterator(encodedText);
          for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
              if (c == '&') {
                  int index = iter.getIndex();
  
                  do {
                      // CHECKSTYLE IGNORE check FOR NEXT 1 LINES
                      c = iter.next();
                  } while (c != CharacterIterator.DONE && c != ';');
  
                  // We found a closing semicolon
                  if (c == ';') {
                      String s = encodedText.substring(index + 1, iter.getIndex());
  
                      if (SPECIAL_ENTITIES.containsKey(s)) {
                          sb.append(SPECIAL_ENTITIES.get(s));
                          continue;
  
                      }
  
                      if (s.length() > 0 && s.charAt(0) == '#') {
                          try {
                              sb.append((char)Short.parseShort(s.substring(1, s.length())));
                              continue;
                          } catch (NumberFormatException nfe) {
                              // This is possible in malformed encodings, but let it fall through
                          }
                      }
                  }
  
                  // Malformed encoding, restore state and pass poorly encoded data back
                  // CHECKSTYLE IGNORE check FOR NEXT 1 LINES
                  c = '&';
                  iter.setIndex(index);
              }
  
              sb.append(c);
  
          }
          return sb.toString();
      }