@Test
  public void testSerialization() throws IOException {
    StringWriter stringWriter = new StringWriter();

    BibEntry entry = new BibEntry("1234", "article");
    // set a required field
    entry.setField("author", "Foo Bar");
    entry.setField("journal", "International Journal of Something");
    // set an optional field
    entry.setField("number", "1");
    entry.setField("note", "some note");

    writer.write(entry, stringWriter, BibDatabaseMode.BIBTEX);

    String actual = stringWriter.toString();

    // @formatter:off
    String expected =
        OS.NEWLINE
            + "@Article{,"
            + OS.NEWLINE
            + "  author  = {Foo Bar},"
            + OS.NEWLINE
            + "  journal = {International Journal of Something},"
            + OS.NEWLINE
            + "  number  = {1},"
            + OS.NEWLINE
            + "  note    = {some note},"
            + OS.NEWLINE
            + "}"
            + OS.NEWLINE;
    // @formatter:on

    assertEquals(expected, actual);
  }
  @Test
  public void roundTripTest() throws IOException {
    // @formatter:off
    String bibtexEntry =
        "@Article{test,"
            + OS.NEWLINE
            + "  Author                   = {Foo Bar},"
            + OS.NEWLINE
            + "  Journal                  = {International Journal of Something},"
            + OS.NEWLINE
            + "  Note                     = {some note},"
            + OS.NEWLINE
            + "  Number                   = {1}"
            + OS.NEWLINE
            + "}";
    // @formatter:on

    // read in bibtex string
    ParserResult result = BibtexParser.parse(new StringReader(bibtexEntry));
    Collection<BibEntry> entries = result.getDatabase().getEntries();
    BibEntry entry = entries.iterator().next();

    // write out bibtex string
    StringWriter stringWriter = new StringWriter();
    writer.write(entry, stringWriter, BibDatabaseMode.BIBTEX);
    String actual = stringWriter.toString();

    assertEquals(bibtexEntry, actual);
  }
  @Test
  public void monthFieldSpecialSyntax() throws IOException {
    // @formatter:off
    String bibtexEntry =
        "@Article{test,"
            + OS.NEWLINE
            + "  Author                   = {Foo Bar},"
            + OS.NEWLINE
            + "  Month                    = mar,"
            + OS.NEWLINE
            + "  Number                   = {1}"
            + OS.NEWLINE
            + "}";
    // @formatter:on

    // read in bibtex string
    ParserResult result = BibtexParser.parse(new StringReader(bibtexEntry));
    Collection<BibEntry> entries = result.getDatabase().getEntries();
    BibEntry entry = entries.iterator().next();

    // modify month field
    Set<String> fields = entry.getFieldNames();
    assertTrue(fields.contains("month"));
    assertEquals("#mar#", entry.getFieldOptional("month").get());

    // write out bibtex string
    StringWriter stringWriter = new StringWriter();
    writer.write(entry, stringWriter, BibDatabaseMode.BIBTEX);
    String actual = stringWriter.toString();

    assertEquals(bibtexEntry, actual);
  }
  @Test
  public void roundTripWithAppendedNewlines() throws IOException {
    // @formatter:off
    String bibtexEntry =
        "@Article{test,"
            + OS.NEWLINE
            + "  Author                   = {Foo Bar},"
            + OS.NEWLINE
            + "  Journal                  = {International Journal of Something},"
            + OS.NEWLINE
            + "  Note                     = {some note},"
            + OS.NEWLINE
            + "  Number                   = {1}"
            + OS.NEWLINE
            + "}\n\n";
    // @formatter:on

    // read in bibtex string
    ParserResult result = BibtexParser.parse(new StringReader(bibtexEntry));
    Collection<BibEntry> entries = result.getDatabase().getEntries();
    BibEntry entry = entries.iterator().next();

    // write out bibtex string
    StringWriter stringWriter = new StringWriter();
    writer.write(entry, stringWriter, BibDatabaseMode.BIBTEX);
    String actual = stringWriter.toString();

    // Only one appending newline is written by the writer, the rest by FileActions. So, these
    // should be removed here.
    assertEquals(bibtexEntry.substring(0, bibtexEntry.length() - 1), actual);
  }
  @Test
  public void testEntryTypeChange() throws IOException {
    // @formatter:off
    String expected =
        OS.NEWLINE
            + "@Article{test,"
            + OS.NEWLINE
            + "  author       = {BlaBla},"
            + OS.NEWLINE
            + "  journal      = {International Journal of Something},"
            + OS.NEWLINE
            + "  number       = {1},"
            + OS.NEWLINE
            + "  note         = {some note},"
            + OS.NEWLINE
            + "  howpublished = {asdf},"
            + OS.NEWLINE
            + "}"
            + OS.NEWLINE;
    // @formatter:on

    // read in bibtex string
    ParserResult result = BibtexParser.parse(new StringReader(expected));
    Collection<BibEntry> entries = result.getDatabase().getEntries();
    BibEntry entry = entries.iterator().next();

    // modify entry
    entry.setType("inproceedings");

    // write out bibtex string
    StringWriter stringWriter = new StringWriter();
    writer.write(entry, stringWriter, BibDatabaseMode.BIBTEX);
    String actual = stringWriter.toString();

    // @formatter:off
    String expectedNewEntry =
        OS.NEWLINE
            + "@InProceedings{test,"
            + OS.NEWLINE
            + "  author       = {BlaBla},"
            + OS.NEWLINE
            + "  number       = {1},"
            + OS.NEWLINE
            + "  note         = {some note},"
            + OS.NEWLINE
            + "  howpublished = {asdf},"
            + OS.NEWLINE
            + "  journal      = {International Journal of Something},"
            + OS.NEWLINE
            + "}"
            + OS.NEWLINE;
    // @formatter:on
    assertEquals(expectedNewEntry, actual);
  }
  @Test
  public void roundTripWithCamelCasingInTheOriginalEntryAndResultInLowerCase() throws IOException {
    // @formatter:off
    String bibtexEntry =
        OS.NEWLINE
            + "@Article{test,"
            + OS.NEWLINE
            + "  Author                   = {Foo Bar},"
            + OS.NEWLINE
            + "  Journal                  = {International Journal of Something},"
            + OS.NEWLINE
            + "  Note                     = {some note},"
            + OS.NEWLINE
            + "  Number                   = {1},"
            + OS.NEWLINE
            + "  HowPublished             = {asdf},"
            + OS.NEWLINE
            + "}";
    // @formatter:on

    // read in bibtex string
    ParserResult result = BibtexParser.parse(new StringReader(bibtexEntry));
    Collection<BibEntry> entries = result.getDatabase().getEntries();
    BibEntry entry = entries.iterator().next();

    // modify entry
    entry.setField("author", "BlaBla");

    // write out bibtex string
    StringWriter stringWriter = new StringWriter();
    writer.write(entry, stringWriter, BibDatabaseMode.BIBTEX);
    String actual = stringWriter.toString();

    // @formatter:off
    String expected =
        OS.NEWLINE
            + "@Article{test,"
            + OS.NEWLINE
            + "  author       = {BlaBla},"
            + OS.NEWLINE
            + "  journal      = {International Journal of Something},"
            + OS.NEWLINE
            + "  number       = {1},"
            + OS.NEWLINE
            + "  note         = {some note},"
            + OS.NEWLINE
            + "  howpublished = {asdf},"
            + OS.NEWLINE
            + "}"
            + OS.NEWLINE;
    // @formatter:on
    assertEquals(expected, actual);
  }
  @Test
  public void roundTripWithPrecedingCommentAndModificationTest() throws IOException {
    // @formatter:off
    String bibtexEntry =
        "% Some random comment that should stay here"
            + OS.NEWLINE
            + "@Article{test,"
            + OS.NEWLINE
            + "  Author                   = {Foo Bar},"
            + OS.NEWLINE
            + "  Journal                  = {International Journal of Something},"
            + OS.NEWLINE
            + "  Note                     = {some note},"
            + OS.NEWLINE
            + "  Number                   = {1}"
            + OS.NEWLINE
            + "}";
    // @formatter:on

    // read in bibtex string
    ParserResult result = BibtexParser.parse(new StringReader(bibtexEntry));
    Collection<BibEntry> entries = result.getDatabase().getEntries();
    BibEntry entry = entries.iterator().next();

    // change the entry
    entry.setField("author", "John Doe");

    // write out bibtex string
    StringWriter stringWriter = new StringWriter();
    writer.write(entry, stringWriter, BibDatabaseMode.BIBTEX);
    String actual = stringWriter.toString();
    // @formatter:off
    String expected =
        "% Some random comment that should stay here"
            + OS.NEWLINE
            + OS.NEWLINE
            + "@Article{test,"
            + OS.NEWLINE
            + "  author  = {John Doe},"
            + OS.NEWLINE
            + "  journal = {International Journal of Something},"
            + OS.NEWLINE
            + "  number  = {1},"
            + OS.NEWLINE
            + "  note    = {some note},"
            + OS.NEWLINE
            + "}"
            + OS.NEWLINE;
    // @formatter:on

    assertEquals(expected, actual);
  }
  private String testSingleWrite(String bibtexEntry) throws IOException {
    // read in bibtex string
    ParserResult result = BibtexParser.parse(new StringReader(bibtexEntry));
    Collection<BibEntry> entries = result.getDatabase().getEntries();
    BibEntry entry = entries.iterator().next();

    // write out bibtex string
    StringWriter stringWriter = new StringWriter();
    writer.write(entry, stringWriter, BibDatabaseMode.BIBTEX);
    String actual = stringWriter.toString();

    assertEquals(bibtexEntry, actual);
    return actual;
  }
  @Test
  public void trimFieldContents() throws IOException {
    StringWriter stringWriter = new StringWriter();

    BibEntry entry = new BibEntry("1234", "article");
    entry.setField("note", "        some note    \t");

    writer.write(entry, stringWriter, BibDatabaseMode.BIBTEX);

    String actual = stringWriter.toString();

    String expected =
        OS.NEWLINE
            + "@Article{,"
            + OS.NEWLINE
            + "  note = {some note},"
            + OS.NEWLINE
            + "}"
            + OS.NEWLINE;

    assertEquals(expected, actual);
  }