/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.hsmf;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.POIReadOnlyDocument;
import org.apache.poi.hmef.attribute.MAPIRtfAttribute;
import org.apache.poi.hsmf.datatypes.AttachmentChunks;
import org.apache.poi.hsmf.datatypes.AttachmentChunks.AttachmentChunksSorter;
import org.apache.poi.hsmf.datatypes.ByteChunk;
import org.apache.poi.hsmf.datatypes.Chunk;
import org.apache.poi.hsmf.datatypes.ChunkGroup;
import org.apache.poi.hsmf.datatypes.Chunks;
import org.apache.poi.hsmf.datatypes.MAPIProperty;
import org.apache.poi.hsmf.datatypes.NameIdChunks;
import org.apache.poi.hsmf.datatypes.PropertyValue;
import org.apache.poi.hsmf.datatypes.PropertyValue.LongPropertyValue;
import org.apache.poi.hsmf.datatypes.PropertyValue.TimePropertyValue;
import org.apache.poi.hsmf.datatypes.RecipientChunks;
import org.apache.poi.hsmf.datatypes.RecipientChunks.RecipientChunksSorter;
import org.apache.poi.hsmf.datatypes.StringChunk;
import org.apache.poi.hsmf.datatypes.Types;
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
import org.apache.poi.hsmf.parsers.POIFSChunkParser;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.CodePageUtil;
import org.apache.poi.util.LocaleUtil;

import static org.apache.logging.log4j.util.Unbox.box;

/**
 * Reads an Outlook MSG File in and provides hooks into its data structure.
 *
 * If you want to develop with HSMF, you might find it worth getting
 *  some of the Microsoft public documentation, such as:
 *
 * [MS-OXCMSG]: Message and Attachment Object Protocol Specification
 */
public class MAPIMessage extends POIReadOnlyDocument {

   /**
    * A MAPI file can be an email (NOTE) or a number of other types
    */
   public enum MESSAGE_CLASS {
      APPOINTMENT,
      CONTACT,
      NOTE,
      POST,
      STICKY_NOTE,
      TASK,
      UNKNOWN,
      UNSPECIFIED
   }

   /** For logging problems we spot with the file */
   private static final Logger LOG = LogManager.getLogger(MAPIMessage.class);

    private Chunks mainChunks;
   private NameIdChunks nameIdChunks;
   private RecipientChunks[] recipientChunks;
   private AttachmentChunks[] attachmentChunks;

   private boolean returnNullOnMissingChunk;

   /**
    * Constructor for creating new files.
    */
   public MAPIMessage() {
      // TODO - make writing possible
      super(new POIFSFileSystem());
   }


   /**
    * Constructor for reading MSG Files from the file system.
    *
    * @param filename Name of the file to read
    * @exception IOException on errors reading, or invalid data
    */
   public MAPIMessage(String filename) throws IOException {
      this(new File(filename));
   }
   /**
    * Constructor for reading MSG Files from the file system.
    *
    * @param file The file to read from
    * @exception IOException on errors reading, or invalid data
    */
   public MAPIMessage(File file) throws IOException {
      this(new POIFSFileSystem(file));
   }

   /**
    * Constructor for reading MSG Files from an input stream.
    *
    * <p>Note - this will buffer the whole message into memory
    *  in order to process. For lower memory use, use {@link #MAPIMessage(File)}
    *
    * @param in The InputStream to buffer then read from
    * @exception IOException on errors reading, or invalid data
    */
   public MAPIMessage(InputStream in) throws IOException {
      this(new POIFSFileSystem(in));
   }
   /**
    * Constructor for reading MSG Files from a POIFS filesystem
    *
    * @param fs Open POIFS FileSystem containing the message
    * @exception IOException on errors reading, or invalid data
    */
   public MAPIMessage(POIFSFileSystem fs) throws IOException {
      this(fs.getRoot());
   }
   /**
    * Constructor for reading MSG Files from a certain
    *  point within a POIFS filesystem
    * @param poifsDir Directory containing the message
    * @exception IOException on errors reading, or invalid data
    */
   public MAPIMessage(DirectoryNode poifsDir) throws IOException {
      super(poifsDir);

      // Grab all the chunks
      ChunkGroup[] chunkGroups = POIFSChunkParser.parse(poifsDir);

      // Grab interesting bits
      ArrayList<AttachmentChunks> attachments = new ArrayList<>();
      ArrayList<RecipientChunks>  recipients  = new ArrayList<>();
      for(ChunkGroup group : chunkGroups) {
         // Should only ever be one of each of these
         if(group instanceof Chunks) {
            mainChunks = (Chunks)group;
         } else if(group instanceof NameIdChunks) {
            nameIdChunks = (NameIdChunks)group;
         } else if(group instanceof RecipientChunks) {
            recipients.add( (RecipientChunks)group );
         }

         // Can be multiple of these - add to list(s)
         if(group instanceof AttachmentChunks) {
            attachments.add( (AttachmentChunks)group );
         }
      }
      attachmentChunks = attachments.toArray(new AttachmentChunks[0]);
      recipientChunks  = recipients.toArray(new RecipientChunks[0]);

      // Now sort these chunks lists so they're in ascending order,
      //  rather than in random filesystem order
      Arrays.sort(attachmentChunks, new AttachmentChunksSorter());
      Arrays.sort(recipientChunks, new RecipientChunksSorter());
   }


   /**
    * Gets a string value based on the passed chunk.
    * @throws ChunkNotFoundException if the chunk isn't there
    */
   public String getStringFromChunk(StringChunk chunk) throws ChunkNotFoundException {
      if(chunk == null) {
         if(returnNullOnMissingChunk) {
            return null;
         } else {
            throw new ChunkNotFoundException();
         }
      }
      return chunk.getValue();
   }


   /**
    * Gets the plain text body of this Outlook Message
    * @return The string representation of the 'text' version of the body, if available.
    * @throws ChunkNotFoundException If the text-body chunk does not exist and
    *       returnNullOnMissingChunk is set
    */
   public String getTextBody() throws ChunkNotFoundException {
      return getStringFromChunk(mainChunks.getTextBodyChunk());
   }

   /**
    * Gets the html body of this Outlook Message, if this email
    *  contains a html version.
    * @return The string representation of the 'html' version of the body, if available.
    * @throws ChunkNotFoundException If the html-body chunk does not exist and
    *       returnNullOnMissingChunk is set
    */
   public String getHtmlBody() throws ChunkNotFoundException {
      ByteChunk htmlBodyBinaryChunk = mainChunks.getHtmlBodyChunkBinary();
      if (htmlBodyBinaryChunk != null) {
         List<PropertyValue> cpid = mainChunks.getProperties().get(MAPIProperty.INTERNET_CPID);
         if (cpid != null && cpid.size() > 0) {
            int codepage = ((LongPropertyValue) cpid.get(0)).getValue();
            try {
               String encoding = CodePageUtil.codepageToEncoding(codepage, true);
               byte[] htmlBodyBinary = htmlBodyBinaryChunk.getValue();
               return new String(htmlBodyBinary, encoding);
            } catch (UnsupportedEncodingException e) {
                LOG.atWarn().log("HTML body binary: Invalid codepage ID {} set for the message via {}, ignoring", box(codepage), MAPIProperty.INTERNET_CPID);
            }
         }
         return htmlBodyBinaryChunk.getAs7bitString();
      }
      return getStringFromChunk(mainChunks.getHtmlBodyChunkString());
   }

   /**
    * Gets the RTF Rich Message body of this Outlook Message, if this email
    *  contains a RTF (rich) version.
    * @return The string representation of the 'RTF' version of the body, if available.
    * @throws ChunkNotFoundException If the rtf-body chunk does not exist and
    *       returnNullOnMissingChunk is set
    */
   public String getRtfBody() throws ChunkNotFoundException {
      ByteChunk chunk = mainChunks.getRtfBodyChunk();
      if(chunk == null) {
         if(returnNullOnMissingChunk) {
            return null;
         } else {
            throw new ChunkNotFoundException();
         }
      }

      try {
         MAPIRtfAttribute rtf = new MAPIRtfAttribute(
               MAPIProperty.RTF_COMPRESSED, Types.BINARY.getId(), chunk.getValue()
         );
         return rtf.getDataString();
      } catch(IOException e) {
         throw new RuntimeException("Shouldn't happen", e);
      }
   }

   /**
    * Gets the subject line of the Outlook Message
    * @throws ChunkNotFoundException If the subject-chunk does not exist and
    *       returnNullOnMissingChunk is set
    */
   public String getSubject() throws ChunkNotFoundException {
      return getStringFromChunk(mainChunks.getSubjectChunk());
   }

   /**
    * Gets the display value of the "FROM" line of the outlook message
    * This is not the actual address that was sent from but the formated display of the user name.
    * @throws ChunkNotFoundException If the from-chunk does not exist and
    *       returnNullOnMissingChunk is set
    */
   public String getDisplayFrom() throws ChunkNotFoundException {
      return getStringFromChunk(mainChunks.getDisplayFromChunk());
   }

   /**
    * Gets the display value of the "TO" line of the outlook message.
    * If there are multiple recipients, they will be separated
    *  by semicolons.
    * This is not the actual list of addresses/values that will be
    *  sent to if you click Reply in the email - those are stored
    *  in {@link RecipientChunks}.
    * @throws ChunkNotFoundException If the to-chunk does not exist and
    *       returnNullOnMissingChunk is set
    */
   public String getDisplayTo() throws ChunkNotFoundException {
      return getStringFromChunk(mainChunks.getDisplayToChunk());
   }

   /**
    * Gets the display value of the "CC" line of the outlook message.
    * If there are multiple recipients, they will be separated
    *  by semicolons.
    * This is not the actual list of addresses/values that will be
    *  sent to if you click Reply in the email - those are stored
    *  in {@link RecipientChunks}.
    * @throws ChunkNotFoundException If the cc-chunk does not exist and
    *       returnNullOnMissingChunk is set
    */
   public String getDisplayCC() throws ChunkNotFoundException {
      return getStringFromChunk(mainChunks.getDisplayCCChunk());
   }

   /**
    * Gets the display value of the "BCC" line of the outlook message.
    * If there are multiple recipients, they will be separated
    *  by semicolons.
    * This is not the actual list of addresses/values that will be
    *  sent to if you click Reply in the email - those are stored
    *  in {@link RecipientChunks}.
    * This will only be present in sent emails, not received ones!
    * @throws ChunkNotFoundException If the bcc-chunk does not exist and
    *       returnNullOnMissingChunk is set
    */
   public String getDisplayBCC() throws ChunkNotFoundException {
      return getStringFromChunk(mainChunks.getDisplayBCCChunk());
   }

   /**
    * Returns all the recipients' email address, separated by
    *  semicolons. Checks all the likely chunks in search of
    *  the addresses.
    */
   public String getRecipientEmailAddress() throws ChunkNotFoundException {
      return toSemicolonList(getRecipientEmailAddressList());
   }
   /**
    * Returns an array of all the recipient's email address, normally
    *  in TO then CC then BCC order.
    * Checks all the likely chunks in search of the addresses.
    */
   public String[] getRecipientEmailAddressList() throws ChunkNotFoundException {
      if(recipientChunks == null || recipientChunks.length == 0) {
         throw new ChunkNotFoundException("No recipients section present");
      }

      String[] emails = new String[recipientChunks.length];
      for(int i=0; i<emails.length; i++) {
         RecipientChunks rc = recipientChunks[i];
         String email = rc.getRecipientEmailAddress();
         if(email != null) {
            emails[i] = email;
         } else {
            if(returnNullOnMissingChunk) {
               emails[i] = null;
            } else {
               throw new ChunkNotFoundException("No email address holding chunks found for the " + (i+1) + "th recipient");
            }
         }
      }

      return emails;
   }


   /**
    * Returns all the recipients' names, separated by
    *  semicolons. Checks all the likely chunks in search of
    *  the names.
    * See also {@link #getDisplayTo()}, {@link #getDisplayCC()}
    *  and {@link #getDisplayBCC()}.
    */
   public String getRecipientNames() throws ChunkNotFoundException {
      return toSemicolonList(getRecipientNamesList());
   }
   /**
    * Returns an array of all the recipient's names, normally
    *  in TO then CC then BCC order.
    * Checks all the likely chunks in search of the names.
    * See also {@link #getDisplayTo()}, {@link #getDisplayCC()}
    *  and {@link #getDisplayBCC()}.
    */
   public String[] getRecipientNamesList() throws ChunkNotFoundException {
      if(recipientChunks == null || recipientChunks.length == 0) {
         throw new ChunkNotFoundException("No recipients section present");
      }

      String[] names = new String[recipientChunks.length];
      for(int i=0; i<names.length; i++) {
         RecipientChunks rc = recipientChunks[i];
         String name = rc.getRecipientName();
         if(name != null) {
            names[i] = name;
         } else {
            throw new ChunkNotFoundException("No display name holding chunks found for the " + (i+1) + "th recipient");
         }
      }

      return names;
   }

   /**
    * Tries to identify the correct encoding for 7-bit (non-unicode)
    *  strings in the file.
    * <p>Many messages store their strings as unicode, which is
    *  nice and easy. Some use one-byte encodings for their
    *  strings, but don't always store the encoding anywhere
    *  helpful in the file.</p>
    * <p>This method checks for codepage properties, and failing that
    *  looks at the headers for the message, and uses these to
    *  guess the correct encoding for your file.</p>
    * <p>Bug #49441 has more on why this is needed</p>
    */
   public void guess7BitEncoding() {
     String generalcodepage = null;
     String htmlbodycodepage = null;
     String bodycodepage = null;
     //
     // General codepage: Message codepage property.
     //
     List<PropertyValue> val = mainChunks.getProperties().get(MAPIProperty.MESSAGE_CODEPAGE);
     if (val != null && val.size() > 0) {
       int codepage = ((LongPropertyValue) val.get(0)).getValue();
       try {
         String encoding = CodePageUtil.codepageToEncoding(codepage, true);
         generalcodepage = encoding;
       } catch (UnsupportedEncodingException e) {
           LOG.atWarn().log("Invalid codepage ID {} set for the message via {}, ignoring", box(codepage), MAPIProperty.MESSAGE_CODEPAGE);
       }
     }
     //
     // General codepage fallback: Message locale ID property.
     //
     if (generalcodepage == null) {
       val = mainChunks.getProperties().get(MAPIProperty.MESSAGE_LOCALE_ID);
       if (val != null && val.size() > 0) {
         int lcid = ((LongPropertyValue) val.get(0)).getValue();
         int codepage = LocaleUtil.getDefaultCodePageFromLCID(lcid);
         try {
           if (codepage != 0) {
             String encoding = CodePageUtil.codepageToEncoding(codepage, true);
             generalcodepage = encoding;
           }
         } catch (UnsupportedEncodingException e) {
             LOG.atWarn().log("Invalid codepage ID {}from locale ID{} set for the message via {}, ignoring", box(codepage),box(lcid), MAPIProperty.MESSAGE_LOCALE_ID);
         }
       }
     }
     //
     // General codepage fallback: Charset on a content type header.
     //
     if (generalcodepage == null) {
       try {
         String[] headers = getHeaders();
         if (headers != null && headers.length > 0) {
           Pattern p = Pattern.compile("content-type:.*?charset=[\"']?([^;'\"]+)[\"']?", Pattern.CASE_INSENSITIVE);
           for (String header : headers) {
             if (header.toLowerCase(LocaleUtil.getUserLocale()).startsWith("content-type")) {
               Matcher m = p.matcher(header);
               if (m.matches()) {
                 String encoding = m.group(1);
                 generalcodepage = encoding;
               }
             }
           }
         }
       } catch (ChunkNotFoundException e) {
       }
     }
     //
     // HTML and text body encoding: Internet CPID property.
     // UTF-8 is ignored for text body. This seems to be a special Outlook behavior.
     //
     val = mainChunks.getProperties().get(MAPIProperty.INTERNET_CPID);
     if (val != null && val.size() > 0) {
       int codepage = ((LongPropertyValue) val.get(0)).getValue();
       try {
         String encoding = CodePageUtil.codepageToEncoding(codepage, true);
         htmlbodycodepage = encoding;
         if (!encoding.equalsIgnoreCase("utf-8")) {
           bodycodepage = encoding;
         }
       } catch (UnsupportedEncodingException e) {
           LOG.atWarn().log("Invalid codepage ID {} set for the message via {}, ignoring", box(codepage), MAPIProperty.INTERNET_CPID);
       }
     }
     //
     // Apply encoding
     //
     set7BitEncoding(generalcodepage, htmlbodycodepage, bodycodepage);
  }

   /**
    * Many messages store their strings as unicode, which is
    *  nice and easy. Some use one-byte encodings for their
    *  strings, but don't easily store the encoding anywhere
    *  in the file!
    * If you know what the encoding is of your file, you can
    *  use this method to set the 7 bit encoding for all
    *  the non unicode strings in the file.
    * @see #guess7BitEncoding()
    */
   public void set7BitEncoding(String charset) {
     set7BitEncoding(charset, charset, charset);
   }
   public void set7BitEncoding(String generalcharset, String htmlbodycharset, String bodycharset) {
      for(Chunk c : mainChunks.getChunks()) {
         if(c instanceof StringChunk) {
           if (c.getChunkId() == MAPIProperty.BODY_HTML.id) {
             if (htmlbodycharset != null) {
               ((StringChunk)c).set7BitEncoding(htmlbodycharset);
             }
           }
           else if (c.getChunkId() == MAPIProperty.BODY.id) {
             if (bodycharset != null) {
               ((StringChunk)c).set7BitEncoding(bodycharset);
             }
           }
           else if (generalcharset != null) {
             ((StringChunk)c).set7BitEncoding(generalcharset);
           }
         }
      }
      if (generalcharset != null) {
        if (nameIdChunks!=null) {
           for(Chunk c : nameIdChunks.getChunks()) {
              if(c instanceof StringChunk) {
                  ((StringChunk)c).set7BitEncoding(generalcharset);
              }
           }
        }
        for(RecipientChunks rc : recipientChunks) {
           for(Chunk c : rc.getAll()) {
              if(c instanceof StringChunk) {
                 ((StringChunk)c).set7BitEncoding(generalcharset);
              }
           }
        }
      }
   }

   /**
    * Does this file contain any strings that
    *  are stored as 7 bit rather than unicode?
    */
   public boolean has7BitEncodingStrings() {
      for(Chunk c : mainChunks.getChunks()) {
         if(c instanceof StringChunk) {
            if( c.getType() == Types.ASCII_STRING ) {
               return true;
            }
         }
      }

      if (nameIdChunks!=null) {
         for(Chunk c : nameIdChunks.getChunks()) {
            if(c instanceof StringChunk) {
               if( c.getType() == Types.ASCII_STRING ) {
                  return true;
               }
            }
         }
      }

      for(RecipientChunks rc : recipientChunks) {
         for(Chunk c : rc.getAll()) {
            if(c instanceof StringChunk) {
               if( c.getType() == Types.ASCII_STRING ) {
                  return true;
               }
            }
         }
      }
      return false;
   }

   /**
    * Returns all the headers, one entry per line
    */
   public String[] getHeaders() throws ChunkNotFoundException {
      String headers = getStringFromChunk(mainChunks.getMessageHeaders());
      if(headers == null) {
         return null;
      }
      return headers.split("\\r?\\n");
   }

   /**
    * Gets the conversation topic of the parsed Outlook Message.
    * This is the part of the subject line that is after the RE: and FWD:
    * @throws ChunkNotFoundException If the conversation-topic chunk does not exist and
    *       returnNullOnMissingChunk is set
    */
   public String getConversationTopic() throws ChunkNotFoundException {
      return getStringFromChunk(mainChunks.getConversationTopic());
   }

   /**
    * Gets the message class of the parsed Outlook Message.
    * (Yes, you can use this to determine if a message is a calendar
    *  item, note, or actual outlook Message)
    * For emails the class will be IPM.Note
    *
    * @throws ChunkNotFoundException If the message-class chunk does not exist and
    *       returnNullOnMissingChunk is set
    */
   public MESSAGE_CLASS getMessageClassEnum() throws ChunkNotFoundException {
      String mc = getStringFromChunk(mainChunks.getMessageClass());
      if (mc == null || mc.trim().length() == 0) {
         return MESSAGE_CLASS.UNSPECIFIED;
      } else if (mc.equalsIgnoreCase("IPM.Note")) {
         return MESSAGE_CLASS.NOTE;
      } else if (mc.equalsIgnoreCase("IPM.Contact")) {
         return MESSAGE_CLASS.CONTACT;
      } else if (mc.equalsIgnoreCase("IPM.Appointment")) {
         return MESSAGE_CLASS.APPOINTMENT;
      } else if (mc.equalsIgnoreCase("IPM.StickyNote")) {
         return MESSAGE_CLASS.STICKY_NOTE;
      } else if (mc.equalsIgnoreCase("IPM.Task")) {
         return MESSAGE_CLASS.TASK;
      } else if (mc.equalsIgnoreCase("IPM.Post")) {
         return MESSAGE_CLASS.POST;
      } else {
          LOG.atWarn().log("I don't recognize message class '{}'. Please open an issue on POI's bugzilla", mc);
         return MESSAGE_CLASS.UNKNOWN;
      }
   }
   /**
    * Gets the date that the message was accepted by the
    *  server on.
    */
   public Calendar getMessageDate() throws ChunkNotFoundException {
      if (mainChunks.getSubmissionChunk() != null) {
         return mainChunks.getSubmissionChunk().getAcceptedAtTime();
      }
      else {
         // Try a few likely suspects...
         for (MAPIProperty prop : new MAPIProperty[] {
               MAPIProperty.CLIENT_SUBMIT_TIME, MAPIProperty.LAST_MODIFICATION_TIME,
               MAPIProperty.CREATION_TIME
         }) {
            List<PropertyValue> val = mainChunks.getProperties().get(prop);
            if (val != null && val.size() > 0) {
               return ((TimePropertyValue)val.get(0)).getValue();
            }
         }
      }

      if(returnNullOnMissingChunk)
         return null;
      throw new ChunkNotFoundException();
   }


   /**
    * Gets the main, core details chunks
    */
   public Chunks getMainChunks() {
      return mainChunks;
   }
   /**
    * Gets all the recipient details chunks.
    * These will normally be in the order of:
    *  * TO recipients, in the order returned by {@link #getDisplayTo()}
    *  * CC recipients, in the order returned by {@link #getDisplayCC()}
    *  * BCC recipients, in the order returned by {@link #getDisplayBCC()}
    */
   public RecipientChunks[] getRecipientDetailsChunks() {
      return recipientChunks;
   }
   /**
    * Gets the Name ID chunks, or
    *  null if there aren't any
    */
   public NameIdChunks getNameIdChunks() {
      return nameIdChunks;
   }
   /**
    * Gets the message attachments.
    */
   public AttachmentChunks[] getAttachmentFiles() {
      return attachmentChunks;
   }


   /**
    * Will you get a null on a missing chunk, or a
    *  {@link ChunkNotFoundException} (default is the
    *  exception).
    */
   public boolean isReturnNullOnMissingChunk() {
      return returnNullOnMissingChunk;
   }

   /**
    * Sets whether on asking for a missing chunk,
    *  you get back null or a {@link ChunkNotFoundException}
    *  (default is the exception).
    */
   public void setReturnNullOnMissingChunk(boolean returnNullOnMissingChunk) {
      this.returnNullOnMissingChunk = returnNullOnMissingChunk;
   }


   private String toSemicolonList(String[] l) {
      StringBuilder list = new StringBuilder();
      boolean first = true;

      for(String s : l) {
         if(s == null) continue;
         if(first) {
            first = false;
         } else {
            list.append("; ");
         }
         list.append(s);
      }

      return list.toString();
   }
}
