super.insertUpdate(ev, null);  ev.end();
  protected void insert(int offset, ElementSpec[] data)    throws BadLocationException  {    if (data == null || data.length == 0)      return;    try      {        // writeLock() and writeUnlock() should always be in a try/finally        // block so that locking balance is guaranteed even if some         // exception is thrown.    writeLock();                // First we collect the content to be inserted.        StringBuffer contentBuffer = new StringBuffer();    for (int i = 0; i < data.length; i++)      {            // Collect all inserts into one so we can get the correct            // ElementEdit        ElementSpec spec = data[i];        if (spec.getArray() != null && spec.getLength() > 0)              contentBuffer.append(spec.getArray(), spec.getOffset(),                                             spec.getLength());      }        int length = contentBuffer.length();        // If there was no content inserted then exit early.        if (length == 0)          return;        UndoableEdit edit = content.insertString(offset,                                                 contentBuffer.toString());        // Create the DocumentEvent with the ElementEdit added        DefaultDocumentEvent ev = new DefaultDocumentEvent(offset,                                   length,                                               DocumentEvent.EventType.INSERT);        ev.addEdit(edit);        // Finally we must update the document structure and fire the insert        // update event.        buffer.insert(offset, length, data, ev);    fireInsertUpdate(ev);        fireUndoableEditUpdate(new UndoableEditEvent(this, ev));      }    finally      {    writeUnlock();  }  }