Program: 36158
Project: 36158
Buggy source:
/** 
 * Replaces the given element in the parent with the contents specified as an HTML string. <p>This will be seen as at least two events, n inserts followed by a remove.</p> <p>When replacing a leaf this will attempt to make sure there is a newline present if one is needed. This may result in an additional element being inserted. Consider, if you were to replace a character element that contained a newline with &lt;img&gt; this would create two elements, one for the image, and one for the newline.</p> <p>If you try to replace the element at length you will most likely end up with two elements, eg <code>setOuterHTML(getCharacterElement (getLength()), "blah")</code> will result in two leaf elements at the end, one representing 'blah', and the other representing the end element.</p> <p>Consider the following structure (the <code>elem</code> parameter is <b>in bold</b>).</p> <pre> &lt;body&gt; | <b>&lt;div&gt;</b> /  \ &lt;p&gt;   &lt;p&gt; </pre> <p>Invoking <code>setOuterHTML(elem, "&lt;ul&gt;&lt;li&gt;")</code> results in the following structure (new elements are <font style="color: red;">in red</font>).</p> <pre> &lt;body&gt; | <font style="color: red;">&lt;ul&gt;</font> \ <font style="color: red;">&lt;li&gt;</font> </pre> <p>If either <code>elem</code> or <code>htmlText</code> parameter is <code>null</code>, no changes are made to the document.</p> <p>For this to work correctly, the document must have an HTMLEditorKit.Parser set. This will be the case if the document was created from an HTMLEditorKit via the <code>createDefaultDocument</code> method.</p>
 * @param elem the element to replace
 * @param htmlText the string to be parsed and inserted in place of <code>elem</code>
 * @throws IllegalStateException if an HTMLEditorKit.Parser has notbeen set
 * @since 1.3
 */
public void setOuterHTML(Element elem,String htmlText) throws BadLocationException, IOException {
  verifyParser();
  if (elem != null && elem.getParentElement() != null && htmlText != null) {
    int start=elem.getStartOffset();
    int end=elem.getEndOffset();
    int startLength=getLength();
    boolean wantsNewline=!elem.isLeaf();
    if (!wantsNewline && (end > startLength || getText(end - 1,1).charAt(0) == NEWLINE[0])) {
      wantsNewline=true;
    }
    Element parent=elem.getParentElement();
    int oldCount=parent.getElementCount();
    insertHTML(parent,start,htmlText,wantsNewline);
    int newLength=getLength();
    if (oldCount != parent.getElementCount()) {
      int removeIndex=parent.getElementIndex(start + newLength - startLength);
      removeElements(parent,removeIndex,1);
    }
  }
}

Fixed version (ground truth):
/** 
 * Replaces the given element in the parent with the contents specified as an HTML string. <p>This will be seen as at least two events, n inserts followed by a remove.</p> <p>When replacing a leaf this will attempt to make sure there is a newline present if one is needed. This may result in an additional element being inserted. Consider, if you were to replace a character element that contained a newline with &lt;img&gt; this would create two elements, one for the image, and one for the newline.</p> <p>If you try to replace the element at length you will most likely end up with two elements, eg <code>setOuterHTML(getCharacterElement (getLength()), "blah")</code> will result in two leaf elements at the end, one representing 'blah', and the other representing the end element.</p> <p>Consider the following structure (the <code>elem</code> parameter is <b>in bold</b>).</p> <pre> &lt;body&gt; | <b>&lt;div&gt;</b> /  \ &lt;p&gt;   &lt;p&gt; </pre> <p>Invoking <code>setOuterHTML(elem, "&lt;ul&gt;&lt;li&gt;")</code> results in the following structure (new elements are <font style="color: red;">in red</font>).</p> <pre> &lt;body&gt; | <font style="color: red;">&lt;ul&gt;</font> \ <font style="color: red;">&lt;li&gt;</font> </pre> <p>If either <code>elem</code> or <code>htmlText</code> parameter is <code>null</code>, no changes are made to the document.</p> <p>For this to work correctly, the document must have an HTMLEditorKit.Parser set. This will be the case if the document was created from an HTMLEditorKit via the <code>createDefaultDocument</code> method.</p>
 * @param elem the element to replace
 * @param htmlText the string to be parsed and inserted in place of <code>elem</code>
 * @throws IllegalStateException if an HTMLEditorKit.Parser has notbeen set
 * @throws BadLocationException if replacement is impossible because ofa structural issue
 * @throws IOException if an I/O exception occurs
 * @since 1.3
 */
public void setOuterHTML(Element elem,String htmlText) throws BadLocationException, IOException {
  verifyParser();
  if (elem != null && elem.getParentElement() != null && htmlText != null) {
    int start=elem.getStartOffset();
    int end=elem.getEndOffset();
    int startLength=getLength();
    boolean wantsNewline=!elem.isLeaf();
    if (!wantsNewline && (end > startLength || getText(end - 1,1).charAt(0) == NEWLINE[0])) {
      wantsNewline=true;
    }
    Element parent=elem.getParentElement();
    int oldCount=parent.getElementCount();
    insertHTML(parent,start,htmlText,wantsNewline);
    int newLength=getLength();
    if (oldCount != parent.getElementCount()) {
      int removeIndex=parent.getElementIndex(start + newLength - startLength);
      removeElements(parent,removeIndex,1);
    }
  }
}