diff --git a/.eslintrc.json b/.eslintrc.json
index e406c09e8b51155d3851935d2ea92cb2a2f6ee89..01faded80601a36803564b31835348860200568e 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,8 +1,24 @@
 {
   "plugins": [
-    "office-addins"
+    "office-addins",
+    "prettier"
   ],
   "extends": [
-    "plugin:office-addins/recommended"
-  ]
+    "plugin:office-addins/recommended",
+    "plugin:prettier/recommended",
+    "esling:recommended"
+  ],
+  "env": {
+    "browser": true,
+    "node": true,
+    "es2021": true
+  },
+  "globals": {
+    "Office": "readonly",  // Declare Office as a global variable
+    "XLSX": "readonly"
+  },
+  "rules": {
+    "no-multiple-empty-lines": "off", // Example: turn off the multiple empty lines rule
+    "prettier/prettier": "error" // Enforce Prettier formatting as ESLint errors
+  }
 }
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000000000000000000000000000000000000..7839c4323d8f48cd428e8805e2f1f29dac11d515
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,8 @@
+{
+  "printWidth": 80,
+  "tabWidth": 2,
+  "semi": true,
+  "singleQuote": true,
+  "trailingComma": "all",
+  "endOfLine": "auto"
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index f250de99d4f1bab06a39b408f2e05623be4bc530..730fcf87e6b38bd51cf271ce2bd415d4513ac970 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,7 +20,7 @@
         "acorn": "^8.11.3",
         "babel-loader": "^9.1.3",
         "copy-webpack-plugin": "^12.0.2",
-        "eslint-plugin-office-addins": "^3.0.2",
+        "eslint-plugin-office-addins": "^3.0.3",
         "file-loader": "^6.2.0",
         "html-loader": "^5.0.0",
         "html-webpack-plugin": "^5.6.0",
diff --git a/package.json b/package.json
index eba23cc140fa66e23b4575897abcef6652de5c7c..79cb0726908d122f2f36041f45044c373c28dbdb 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,7 @@
     "acorn": "^8.11.3",
     "babel-loader": "^9.1.3",
     "copy-webpack-plugin": "^12.0.2",
-    "eslint-plugin-office-addins": "^3.0.2",
+    "eslint-plugin-office-addins": "^3.0.3",
     "file-loader": "^6.2.0",
     "html-loader": "^5.0.0",
     "html-webpack-plugin": "^5.6.0",
@@ -59,4 +59,4 @@
     "last 2 versions",
     "ie 11"
   ]
-}
\ No newline at end of file
+}
diff --git a/src/taskpane/taskpane.html b/src/taskpane/taskpane.html
index e2f2d4f94c79f28919c08dfd89a7fded1974fbd6..58e8afe02c9e626421b8d20484e75840129de25d 100644
--- a/src/taskpane/taskpane.html
+++ b/src/taskpane/taskpane.html
@@ -15,12 +15,19 @@
     <p id="messageText"></p>
   </div>
 
-  <fieldset>
+  <!--fieldset>
     <legend>1. Select data source (Excel file):</legend>
     <input type="file" id="excelFileInput" accept=".xlsx, .xlsm, .xlsb, .xlts, .xltm, .xls" />
     <div class="worksheet_select">Worksheet: <select id="worksheetSelect" disabled></select></div>
+  </fieldset-->
+  <fieldset>
+    <legend>1. Select data source (Excel file):</legend>
+    <button id="selectFileButton">Select File</button>
+    <span id="selectedFileName" style="margin-left: 10px; font-slant: italic;">No file selected</span>
+    <div class="worksheet_select">
+      Worksheet: <select id="worksheetSelect" disabled></select>
+    </div>
   </fieldset>
-
  
   <fieldset>
     <legend>2. E-Mail - Placeholder fields:</legend>
@@ -50,9 +57,12 @@
     </div>
   </fieldset>
 
+  <button id="sendNowButton" disabled>Send now</button>
+  <button id="sendLaterButton" disabled>Send later</button>
+
 
   <div id="dataPreview"></div>
-  <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
+  <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script>
   <script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
   <script src="taskpane.js"></script>
 </div>
diff --git a/src/taskpane/taskpane.js b/src/taskpane/taskpane.js
index 4603f55ad2368f7d219cda119c448e0dfafde595..4ecab959ef08f944c49e25cd1678240cc5a0344e 100644
--- a/src/taskpane/taskpane.js
+++ b/src/taskpane/taskpane.js
@@ -2,10 +2,11 @@
  * Copyright (c) 2025 Reinhold Kainhofer, Open Tools, office@open-tools.net
  */
 
+
 // Ensure the Office.js library is loaded the office context is fully initialized!
 Office.onReady(function (info) {
   // Office is ready
-  if (info.host === Office.HostType.Outlook) {
+/*  if (info.host === Office.HostType.Outlook) {
     // Now you can safely use Office.context.mailbox
     Office.context.mailbox.item.body.getTypeAsync((result) => {
       if (result.status === Office.AsyncResultStatus.Succeeded) {
@@ -14,18 +15,30 @@ Office.onReady(function (info) {
         console.error("Failed to get body type:", result.error);
       }
     });
-  }
+  }*/
 });
 
+
 let workbook = null;
+let worksheetData = []; // Holds the JSON data from the selected worksheet
+
+let excelFileHandle = null;
+let attachmentsFolderHandle = null;
+
+
+
+
 // Create a global EventTarget instance
 const eventBus = new EventTarget();
 
 
+
+/***
+ * displayMessage: Warning/Errors in a temporary, non-blocking popup div
+ */
 function displayMessage(message) {
   const messageDiv = document.getElementById("messageDiv");
   const messageText = document.getElementById("messageText");
-  const closeButton = document.getElementById("closeMessageButton");
 
   // Set the message text
   messageText.textContent = message;
@@ -40,67 +53,123 @@ function displayMessage(message) {
       messageDiv.classList.remove("show", "hide");
     }, 300);
   }, 5000); // Hide the message after 5 seconds
+}
 
-  // Close button functionality
-  closeButton.addEventListener("click", function() {
-    messageDiv.classList.add("hide");
-    setTimeout(() => {
-      messageDiv.classList.remove("show", "hide");
-    }, 300); // Remove the show and hide classes after the fade-out animation
-  });
+// Close button functionality
+document.getElementById("closeMessageButton").addEventListener("click", function () {
+  const messageDiv = document.getElementById("messageDiv");
+  messageDiv.classList.add("hide");
+  setTimeout(() => {
+    messageDiv.classList.remove("show", "hide");
+  }, 300); // Remove the show and hide classes after the fade-out animation
+});
 
-}
 
 
 
 
 /***********************************************************
  * 1. Select data source (Excel worksheet, CSV file etc.)
- * 
+ *
  * After selecting the file, potentially multiple sheets / tables are available for selection
- * 
+ *
  ***********************************************************/
 
 const worksheetSelect = document.getElementById("worksheetSelect");
-
-document.getElementById("excelFileInput").addEventListener("change", handleFile);
 worksheetSelect.addEventListener("change", handleWorksheetSelection);
 
+document.getElementById("selectFileButton").addEventListener("click", async () => {
+  try {
+    // Open the file picker and allow selecting a single file
+/*    if (!('showOpenFilePicker' in window)) {
+      displayMessage("File picker API is not supported in this browser.");
+      return;
+    }*/
+    const [handle] = await window.showOpenFilePicker({
+      types: [
+        {
+          description: "Spreadsheet Files",
+          accept: {
+            "application/vnd.ms-excel": [".xlsx", ".xlsm", ".xlsb", ".xls"],
+            "application/vnd.oasis.opendocument.spreadsheet": [".ods"],
+            "text/csv": [".csv"],
+            "text/plain": [".txt"],
+          },
+        },
+      ],
+      multiple: false,
+    });
+
+    const setSpreadsheetEvent = new CustomEvent("setSpreadsheetFile", {
+      detail: {
+        handle: handle, // Pass the file handle
+      },
+    });
+    eventBus.dispatchEvent(setSpreadsheetEvent);
+  } catch (err) {
+    console.error("File selection canceled or failed", err);
+  }
+});
 
-/* 
+
+
+
+/*
  * Read the selected file (Excel, csv) into memory
  */
-function handleFile(event) {
-  const file = event.target.files[0];
-  if (!file) return;
-
-  const reader = new FileReader();
-  reader.onload = function (e) {
-    const data = new Uint8Array(e.target.result);
-    const binary = Array.from(data).map(byte => String.fromCharCode(byte)).join('');
-    const fileType = file.name.split(".").pop().toLowerCase();
-
-    // Determine the file type and parse accordingly
-    if (fileType === "xlsb") {
-      workbook = XLSX.read(binary, { type: "binary" });
-    } else {
-      workbook = XLSX.read(data, { type: "array" });
-    }
+eventBus.addEventListener("setSpreadsheetFile", async (event) => {
+  // Save the file handle for later access
+  const handle = event.detail.handle;
+  if (!handle) return;
+
+  const permissionStatus = await handle.queryPermission();
+  if (permissionStatus !== 'granted') {
+    // Prompt user to grant permission again
+    await handle.requestPermission();
+    console.log('Permission is required for this file!');
+    // TODO: exit if permission was not granted!
+  }
+
+  excelFileHandle = handle;
+  saveHandles();
+      
+  // Display the file name
+  document.getElementById("selectedFileName").textContent = handle.name;
+    
+  const file = await handle.getFile();
+  const fileType = file.name.split('.').pop().toLowerCase();
+  const arrayBuffer = await file.arrayBuffer();
+        
+  if (fileType === 'csv' || fileType === 'txt') {
+    // Convert text content to a SheetJS workbook
+    const text = await file.text();
+    workbook = XLSX.read(text, { type: 'string' });
+  } else {
+    // For binary files (.xlsx, .ods)
+    workbook = XLSX.read(arrayBuffer, { type: 'array' });
+  }
+  const sheetNames = workbook.SheetNames;
+          
+  // Populate the worksheet dropdown
+  populateWorksheetDropdown(sheetNames);
+});
 
-    populateWorksheetDropdown();
-  };
 
-  reader.readAsArrayBuffer(file);
-}
 
-/* 
+/*
  * Make the list of worksheets selectable in a combo box and auto-select the first one
  */
-function populateWorksheetDropdown() {
+function populateWorksheetDropdown(sheetNames) {
+  if (!sheetNames || sheetNames.length === 0) {
+    worksheetSelect.disabled = true;
+    displayMessage("No worksheets found in the workbook.")
+    console.error("No worksheets found in the workbook.");
+    return;
+  }
   worksheetSelect.innerHTML = "";
   worksheetSelect.disabled = false;
 
-  workbook.SheetNames.forEach((sheetName) => {
+  sheetNames.forEach((sheetName) => {
     const option = document.createElement("option");
     option.value = sheetName;
     option.textContent = sheetName;
@@ -108,27 +177,27 @@ function populateWorksheetDropdown() {
   });
 
   // Automatically select the first worksheet and trigger the "change" event
-  if (worksheetSelect.options.length >= 1) {
+  if (worksheetSelect.options.length > 0) {
     worksheetSelect.selectedIndex = 0;
-    worksheetSelect.dispatchEvent(new Event("change"));
   }
+  worksheetSelect.dispatchEvent(new Event("change"));
 }
 
 function handleWorksheetSelection(event) {
   const sheetName = event.target.value;
-  if (!sheetName) return;
-  if (!workbook) return; // no file loaded yet!
+  if (!workbook || !sheetName) return;// no file loaded yet or no workseet selected!
 
   // Populate the placeholders combobox and the attachments column combo
   const worksheet = workbook.Sheets[sheetName];
   const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
-  const columns = jsonData[0] || [];
+  worksheetData = jsonData;
 
+  const columns = jsonData[0] || [];
   const dataReadyEvent = new CustomEvent("dataReady", {
     detail: {
-      data: jsonData,               // Pass the loaded data as part of the event
-      columns: columns, // Pass the availabe column names 
-    }
+      data: jsonData, // Pass the loaded data
+      columns: columns, // Pass the availabe column names
+    },
   });
   eventBus.dispatchEvent(dataReadyEvent);
 }
@@ -138,12 +207,12 @@ function handleWorksheetSelection(event) {
 
 /***********************************************************
  * 2. E-Mail Contents - Allow inserting placeholders from the available column
- * 
+ *
  * After selecting the file and sheet, a combobox with all available placeholders is provided
  * Next to is is a "Insert" button, which inserts the placeholder of the form {%fieldname%} 
  * into the mail at the current position. For Subject, To/CC/BCC we cannot automatically insert,
  * but at least provide a copy button to copy the placeholder into the clipboard (TODO!)
- * 
+ *
  ***********************************************************/
 
 const placeholderSelect = document.getElementById("placeholderSelect");
@@ -153,18 +222,33 @@ const placeholderCopyLabel = document.getElementById("placeholderCopyLabel");
 // Attach event listener to the previous controls / eventbus
 placeholderSelect.addEventListener("change", enablePlaceholderInsert);
 placeholderInsertButton.addEventListener("click", insertPlaceholder);
-placeholderCopyLabel.addEventListener("click", copyPlaceholderToClipboard)
+placeholderCopyLabel.addEventListener("click", copyPlaceholderToClipboard);
 eventBus.addEventListener("dataReady", populatePlaceholderSelect);
 
 function populatePlaceholderSelect(event) {
   const columns = event.detail.columns;
+  const currentSelectedValue = placeholderSelect.value;
   placeholderSelect.innerHTML = "";
+
   columns.forEach((column, index) => {
     const option = document.createElement("option");
-    option.value = index;
+    option.value = column;
     option.textContent = column || `Column ${index + 1}`;
     placeholderSelect.appendChild(option);
   });
+
+  // Check if the previously selected value exists in the new list
+  const matchingOption = Array.from(attachmentColumnSelect.options).find(option =>
+    option.value === currentSelectedValue || option.textContent === currentSelectedValue
+  );
+  
+  // If the selected value is found, restore it
+  if (matchingOption) {
+    attachmentColumnSelect.value = currentSelectedValue;
+  } else if (columns.length > 0) {
+    // If no match is found, default to the first option
+    attachmentColumnSelect.value = columns[0];
+  }
   placeholderSelect.disabled = false;
   placeholderSelect.dispatchEvent(new Event("change"));
 }
@@ -175,12 +259,10 @@ function enablePlaceholderInsert(event) {
 }
 
 
-
 // Function to insert placeholder
 async function insertPlaceholder() {
   try {
     // Get the selected field from the combo box
-//    const selectedField = placeholderSelect.value;
     const selectedText = placeholderSelect.options[placeholderSelect.selectedIndex].text;
 
     if (!selectedText) {
@@ -191,16 +273,17 @@ async function insertPlaceholder() {
     const placeholder = `{%${selectedText}%}`;
 
     // Use the Office.js API to get the current item
-    await Office.context.mailbox.item.body.getTypeAsync(async (result) => {
+    Office.context.mailbox.item.body.getTypeAsync((result) => {
       if (result.status === Office.AsyncResultStatus.Succeeded) {
         const bodyType = result.value;
-
         if (bodyType === Office.MailboxEnums.BodyType.Html) {
-          // Insert HTML placeholder into the body
-          await Office.context.mailbox.item.body.setSelectedDataAsync(placeholder, { coercionType: Office.CoercionType.Html } );
-        } else if (bodyType === Office.MailboxEnums.BodyType.Text) {
-          // Insert plain text placeholder into the body
-          await Office.context.mailbox.item.body.setSelectedDataAsync(placeholder, { coercionType: Office.CoercionType.Text } );
+          return Office.context.mailbox.item.body.setSelectedDataAsync(placeholder, {
+            coercionType: Office.CoercionType.Html,
+          });
+        } else {
+          return Office.context.mailbox.item.body.setSelectedDataAsync(placeholder, {
+            coercionType: Office.CoercionType.Text,
+          });
         }
       }
     });
@@ -211,12 +294,12 @@ async function insertPlaceholder() {
 }
 
 
-/* 
+/*
  * Function to insert the placeholder into other fields 
  * -> TODO: Add a dropdown to the "Insert" button to append to Subject/To/CC/BCC alternatively!
  */
 
-async function insertIntoField(field, placeholder) {
+/*async function insertIntoField(field, placeholder) {
   try {
     const currentValue = await Office.context.mailbox.item[field].getAsync();
     if (currentValue.status === Office.AsyncResultStatus.Succeeded) {
@@ -228,10 +311,10 @@ async function insertIntoField(field, placeholder) {
   }
 }
 
-
 // Example usage:
 // insertIntoField('subject', '{%fieldname%}');
 // insertIntoField('to', '{%fieldname%}');
+*/
 
 
 
@@ -245,12 +328,14 @@ function copyPlaceholderToClipboard() {
   }
 
   const placeholder = `{%${selectedText}%}`;
-  navigator.clipboard.writeText(placeholder).then(() => {
-    displayMessage("Copied to clipboard!");
+  navigator.clipboard
+    .writeText(placeholder)
+    .then(() => {
+      displayMessage("Copied to clipboard!");
     })
     .catch((err) => {
       console.error("Error copying to clipboard:", err);
-  });
+    });
 }
 
 
@@ -258,46 +343,73 @@ function copyPlaceholderToClipboard() {
 
 /***********************************************************
  * 3. Attachments handling
- * 
+ *
  * Provide a combobox to select the column for individual attachments,
- * optionally appends a file extension (e.g. "pdf") and select 
+ * optionally appends a file extension (e.g. "pdf") and select
  * a folder where the attachments are stored.
- * 
+ *
  ***********************************************************/
 
 const attachmentColumnSelect = document.getElementById("attachmentColumnSelect");
 const appendExtensionCheckbox = document.getElementById("appendExtensionCheckbox");
 const fileExtensionInput = document.getElementById("fileExtensionInput");
-const attachmentFolderButton = document.getElementById('selectAttachmentFolderButton');
-const attachmentFolderSpan = document.getElementById('selectedAttachmentFolder');
-
+const attachmentFolderButton = document.getElementById("selectAttachmentFolderButton");
+const attachmentFolderSpan = document.getElementById("selectedAttachmentFolder");
 
 eventBus.addEventListener("dataReady", populateAttachmentColumnSelect);
 attachmentColumnSelect.addEventListener("change", handleAttachmentColumnSelection);
 
-
 function populateAttachmentColumnSelect(event) {
+  // (Re-)Populate the column selection combobox. -> Store the current selection and reinstate it after re-filling the list!
   const columns = event.detail.columns;
-  attachmentColumnSelect.innerHTML = '<option value="">Select Column</option>';
+  // Store the currently selected value
+  const currentSelectedValue = attachmentColumnSelect.value;
+
+  attachmentColumnSelect.innerHTML = '<option value="">No attachment (select column if needed)</option>';
   columns.forEach((column, index) => {
     const option = document.createElement("option");
-    option.value = index;
+    option.value = column;
     option.textContent = column || `Column ${index + 1}`;
     attachmentColumnSelect.appendChild(option);
   });
+
+  // Check if the previously selected value exists in the new list
+  const matchingOption = Array.from(attachmentColumnSelect.options).find(option =>
+    option.value === currentSelectedValue || option.textContent === currentSelectedValue
+  );
+
+  // If the selected value is found, restore it
+  if (matchingOption) {
+    attachmentColumnSelect.value = currentSelectedValue;
+  } else if (columns.length > 0) {
+    // If no match is found, default to the first option
+    attachmentColumnSelect.value = columns[0];
+  }
   attachmentColumnSelect.disabled = false;
+  attachmentColumnSelect.dispatchEvent(new Event("change"));
 }
 
 
-
 appendExtensionCheckbox.addEventListener("change", () => {
   fileExtensionInput.disabled = !appendExtensionCheckbox.checked;
 });
 attachmentFolderButton.addEventListener("click", async () => {
   try {
-    // TODO: This does not seem to work with the web-application of Outlook!
-    const directoryHandle = await window.showDirectoryPicker(); 
-    attachmentFolderSpan.textContent = `Selected folder: ${directoryHandle.name}`;
+    // If the directory Picker is not supported, show a warning until we find a solution... TODO
+    if (typeof window.showDirectoryPicker === "undefined") {
+      console.warn("Directory picker API is not supported in this browser.");
+      displayMessage("Directory picker API is not supported in this browser.");
+      return;
+    }
+
+    const directoryHandle = await window.showDirectoryPicker();
+    const setAttachmentFolderEvent = new CustomEvent("setAttachmentsFolder", {
+      detail: {
+        handle: directoryHandle, // Pass the file handle
+      },
+    });
+    eventBus.dispatchEvent(setAttachmentFolderEvent);
+
     console.log("Selected folder:", directoryHandle);
   } catch (err) {
     console.error("Folder selection cancelled or failed", err);
@@ -305,6 +417,33 @@ attachmentFolderButton.addEventListener("click", async () => {
 });
 
 
+/*
+* Set the selected folder handle as attachments folder:
+*  - store in global variable for mail sending
+*  - display name in label
+*  - store in persistent storage to survive reloads
+*/
+eventBus.addEventListener("setAttachmentsFolder", async (event) => {
+  // Save the file handle for later access
+  const handle = event.detail.handle;
+  if (!handle) return;
+  
+  const permissionStatus = await handle.queryPermission();
+  if (permissionStatus !== 'granted') {
+    // Prompt user to grant permission again
+    await handle.requestPermission();
+    console.log('Permission is required for this file!');
+    // TODO: exit if permission was not granted!
+  }
+  
+  attachmentsFolderHandle = handle; // Update the global variable
+  saveHandles();
+  attachmentFolderSpan.textContent = `Selected folder: ${handle.name}`;
+});
+
+
+
+
 
 function handleAttachmentColumnSelection() {
   if (attachmentColumnSelect.value !== "") {
@@ -323,9 +462,9 @@ function handleAttachmentColumnSelection() {
 
 /***********************************************************
  * 4. Sanity Checks, general data handling and review
- * 
- * 
- * 
+ *
+ *
+ *
  ***********************************************************/
 
 eventBus.addEventListener("dataReady", displayData);
@@ -360,11 +499,45 @@ function displayData(event) {
 
 /***********************************************************
  * 5. Mail sending
- * 
- * 
- * 
+ *
+ *
+ *
  ***********************************************************/
 
+const sendNowButton = document.getElementById("sendNowButton");
+const sendLaterButton = document.getElementById("sendLaterButton");
+
+
+attachmentColumnSelect.addEventListener("change", handleAttachmentColumnSelection);
+eventBus.addEventListener("dataReady", async () => {
+  sendNowButton.disabled = false;
+  sendLaterButton.disabled = false;
+});
+
+
+
+sendNowButton.addEventListener("click", async () => {
+  try {
+    sendSerialMails(/*sendNow=*/ true);
+  } catch (err) {
+    console.error("Error sending mails: ", err);
+  }
+});
+
+sendLaterButton.addEventListener("click", async () => {
+  try {
+    sendSerialMails(/*sendNow=*/ false);
+  } catch (err) {
+    console.error("Error sending mails: ", err);
+  }
+});
+
+
+
+
+
+
+
 
 function replacePlaceholders(template, row) {
   return template.replace(/{%([^%]+)%}/g, (match, columnName) => {
@@ -372,82 +545,268 @@ function replacePlaceholders(template, row) {
   });
 }
 
-async function addAttachment(mailItem, filePath, fileName) {
-  const attachmentUrl = `${filePath}/${fileName}`;
+async function addAttachment(mailItem, folderHandle, fileName) {
   try {
-    await mailItem.addFileAttachmentAsync(attachmentUrl, fileName);
+    // Step 1: Get the file handle from the directory and file name
+    const fileHandle = await folderHandle.getFileHandle(fileName);
+    
+    // Step 2: Request permission if necessary (query for permission)
+    const permissionStatus = await fileHandle.queryPermission();
+    if (permissionStatus !== 'granted') {
+      // Request permission from the user if needed
+      await fileHandle.requestPermission();
+    }
+
+    // Step 3: Get the file data (Blob) from the file handle
+    const file = await fileHandle.getFile();
+    const fileBlob = file; // You can use file as a Blob object
+    
+    // Step 4: Attach the file to the email
+    mailItem.attachments.addFileAttachment(fileBlob, file.name)
+      .then(() => {
+        console.log(`File "${file.name}" successfully attached to the email.`);
+      })
+      .catch((error) => {
+        console.error('Error attaching file:', error);
+      });
   } catch (error) {
-    console.error("Error adding attachment:", error);
+    console.error('Error accessing or attaching the file:', error);
   }
 }
 
-async function sendSerialMails(data, filePath, sendOrSave) {
+
+async function sendSerialMails(sendNow = false) {
+  if (!worksheetData || worksheetData.length === 0) {
+    displayMessage("No data available to send emails. Please select a worksheet.");
+    return;
+  }
+
   const item = Office.context.mailbox.item;
+  const attachmentColumn = attachmentColumnSelect.options[attachmentColumnSelect.selectedIndex].text;
+  const hasAttachmentsConfigured = attachmentColumn && attachmentsFolderHandle;
+
+  let fileExtension = appendExtensionCheckbox.checked ? fileExtensionInput.value : "";
+  if (fileExtension && !fileExtension.startsWith(".")) {
+    fileExtension = `.${fileExtension}`;
+  }
+        
+  for (const row of worksheetData) {
+    try {
+      // Function to get the recipient list as a string (if available)
+      async function getRecipientAsync(recipientField) {
+        return new Promise((resolve, reject) => {
+          recipientField.getAsync((result) => {
+            if (result.status === Office.AsyncResultStatus.Succeeded) {
+              // Extract the email addresses (or return empty string if none)
+              const emails = result.value.map((recipient) => recipient.emailAddress).join(", ");
+              resolve(emails); // Join multiple recipients with a comma
+            } else {
+              reject("Error retrieving recipient");
+            }
+          });
+        });
+      }
+
+
+      // Fetch recipients asynchronously and replace placeholders
+      const to = await getRecipientAsync(item.to);
+      const cc = await getRecipientAsync(item.cc);
+      const bcc = await getRecipientAsync(item.bcc);
+      const subject = replacePlaceholders(String(item.subject), row);
+      
+
+      const bodyResult = await item.body.getAsync(Office.CoercionType.Html);
+      const body = replacePlaceholders(bodyResult.value || "", row);
+
+      // Create a copy of the email
+      const mailItem = await Office.context.mailbox.item.displayReplyAllFormAsync();
+
+      // Replace fields
+      const new_to = replacePlaceholders(to, row);
+      const new_cc = replacePlaceholders(cc, row);
+      const new_bcc = replacePlaceholders(bcc, row);
+      const new_subject = replacePlaceholders(item.subject, row);
+      if (to != new_to)
+        mailItem.to = new_to;
+      if (cc != new_cc)
+        mailItem.cc = new_cc;
+      if (bcc != new_bcc)
+        mailItem.bcc = new_bcc;
+      if (subject != new_subject)
+        mailItem.subject = new_subject;
+      mailItem.body.setAsync(body, { coercionType: Office.CoercionType.Html });
+
+      // Handle attachment only if configuration and data are available
+      if (hasAttachmentsConfigured && attachmentColumn) {
+        const attachmentFileName = row[attachmentColumn];
+        if (attachmentFileName) {
+          let formattedFileName = attachmentFileName.trim();
+
+          // Ensure the file name has the correct extension
+          if (fileExtension && !formattedFileName.endsWith(fileExtension)) {
+            formattedFileName += fileExtension;
+          }
+
+          try {
+            await addAttachment(mailItem, attachmentsFolderHandle, formattedFileName);
+          } catch (error) {
+            console.warn(`Skipping attachment for row: ${JSON.stringify(row)}, reason: ${error.message}`);
+          }
+        }
+      }
+
+      // Save the mail as a draft or send immediately
+      if (sendNow) {
+        await mailItem.sendAsync();
+        console.log("Mails sent immediately.");
+      } else {
+        await mailItem.saveAsync();
+        console.log("Mails saved as draft.");
+      }
 
-  for (const row of data) {
-    const to = row["To"];
-    const cc = row["CC"];
-    const bcc = row["BCC"];
-    const subject = replacePlaceholders(item.subject, row);
-    const body = replacePlaceholders(item.body.getAsync(Office.CoercionType.Html).value, row);
-    const attachmentFile = row["AttachmentFileName"];
-
-    // Create a copy of the email
-    const mailItem = await Office.context.mailbox.item.displayReplyAllFormAsync();
-
-    // Replace fields
-    mailItem.to = to;
-    mailItem.cc = cc;
-    mailItem.bcc = bcc;
-    mailItem.subject = subject;
-    mailItem.body.setAsync(body, { coercionType: Office.CoercionType.Html });
-
-    // Add attachment
-    if (attachmentFile) {
-      await addAttachment(mailItem, filePath, attachmentFile);
+    } catch (error) {
+      console.error("Error processing row:", JSON.stringify(row), "Error:", error);
     }
+  }
+  displayMessage("Mails sent!");
+}
+
 
-    // Send the mail
-    await mailItem.sendAsync();
+
+
+
+/***********************************************************
+ * 6. Persisting form settings across sessions: Use Office.js Storage
+ *
+ *
+ *
+ ***********************************************************/
+
+worksheetSelect.addEventListener("change", saveFormDataToRoaming);
+placeholderSelect.addEventListener("change", saveFormDataToRoaming);
+attachmentColumnSelect.addEventListener("change", saveFormDataToRoaming);
+appendExtensionCheckbox.addEventListener("change", saveFormDataToRoaming);
+fileExtensionInput.addEventListener("input", saveFormDataToRoaming);
+attachmentFolderSpan.addEventListener("click", saveFormDataToRoaming); // TODO: This should be called AFTER the folder picker was used!
+
+function saveFormDataToRoaming() {
+  const formData = {
+    worksheetName: worksheetSelect.value,
+    placeholder: placeholderSelect.value,
+    attachmentColumn: attachmentColumnSelect.value,
+    appendExtension: appendExtensionCheckbox.checked,
+    fileExtension: fileExtensionInput.value,
+  };
+  Office.context.roamingSettings.set('mailMergeFormData', formData);
+  Office.context.roamingSettings.saveAsync();
+}
+
+function loadFormDataFromRoaming() {
+  const formData = Office.context.roamingSettings.get('mailMergeFormData');
+  if (formData) {
+    worksheetSelect.value = formData.worksheetName || '';
+    placeholderSelect.value = formData.placeholder || '';
+    attachmentColumnSelect.value = formData.attachmentColumn || '';
+    appendExtensionCheckbox.checked = formData.appendExtension || false;
+    fileExtensionInput.value = formData.fileExtension || '';
+
+    handleAttachmentColumnSelection();
   }
 }
-async function saveSerialMailsAsDrafts(data, filePath) {
-  const item = Office.context.mailbox.item;
 
-  for (const row of data) {
-    const to = row["To"];
-    const cc = row["CC"];
-    const bcc = row["BCC"];
-    const subject = replacePlaceholders(item.subject, row);
-    const body = replacePlaceholders(item.body.getAsync(Office.CoercionType.Html).value, row);
-    const attachmentFile = row["AttachmentFileName"];
-
-    // Create a new draft mail
-    const mailItem = await Office.context.mailbox.item.displayReplyAllFormAsync();
-
-    // Replace fields
-    mailItem.to = to;
-    mailItem.cc = cc;
-    mailItem.bcc = bcc;
-    mailItem.subject = subject;
-    mailItem.body.setAsync(body, { coercionType: Office.CoercionType.Html });
-
-    // Add attachment
-    if (attachmentFile) {
-      try {
-        await addAttachment(mailItem, filePath, attachmentFile);
-      } catch (error) {
-        console.warn(`Attachment not found for row: ${JSON.stringify(row)}`);
+// Function to open or create the IndexedDB database
+async function openIndexedDB() {
+  return new Promise((resolve, reject) => {
+    const request = indexedDB.open('fileHandlesDB', 1);  // Open or create the database
+
+    request.onupgradeneeded = (event) => {
+      const db = event.target.result;
+      // Create the object store if it doesn't exist
+      if (!db.objectStoreNames.contains('fileHandles')) {
+        db.createObjectStore('fileHandles');
       }
+    };
+
+    request.onsuccess = (event) => {
+      resolve(event.target.result); // Return the database instance
+    };
+
+    request.onerror = (event) => {
+      reject('Error opening IndexedDB:', event.target.error);
+    };
+  });
+}
+
+
+// Save file/directory handles persistently
+async function saveHandles() {
+  // Storing/loading handles to/from Office Storage API does not work:
+/*  const settings = {
+    excelFileHandle: excelFileHandle ? await excelFileHandle.queryPermission() : null,
+    attachmentsFolderHandle: attachmentsFolderHandle ? await attachmentsFolderHandle.queryPermission() : null,
+  };
+  Office.context.roamingSettings.set("fileHandles", settings);
+  Office.context.roamingSettings.saveAsync();
+  */
+
+  // Instead, try storing it to indexDB instead:
+  const db = await openIndexedDB();
+  if (db) {
+    const transaction = db.transaction(['fileHandles'], 'readwrite');
+    const store = transaction.objectStore('fileHandles');
+
+    const data = {
+      excelFileHandle: excelFileHandle,
+      attachmentsFolderHandle: attachmentsFolderHandle,
+    };
+    store.put(data, 'fileHandles'); // Storing the metadata
+    await transaction.complete;
+  }
+}
+
+// Load file/directory handles persistently
+async function loadHandles() {
+//  const settings = Office.context.roamingSettings.get("fileHandles"); // Storing/loading handles to/from Office Storage API does not work!
+  const settings = await loadFromIndexedDB('fileHandles'); // Instead, try loading them from indexDB instead:
+
+  if (settings) {
+    if (settings.excelFileHandle) {
+      const setSpreadsheetEvent = new CustomEvent("setSpreadsheetFile", {
+        detail: { handle: settings.excelFileHandle, },
+      });
+      eventBus.dispatchEvent(setSpreadsheetEvent);
     }
 
-    // Save the mail as a draft or send immediately
-    try {
-      await mailItem.saveAsync();
-//    await mailItem.sendAsync();
-      console.log("Mail saved as draft.");
-    } catch (error) {
-      console.error("Error saving draft:", error);
+    if (settings.attachmentsFolderHandle) {
+      const setAttachmentsFolderEvent = new CustomEvent("setAttachmentsFolder", {
+        detail: { handle: settings.attachmentsFolderHandle, },
+      });
+      eventBus.dispatchEvent(setAttachmentsFolderEvent);
     }
   }
 }
+
+ 
+// Example pseudo-function for IndexedDB
+async function loadFromIndexedDB(storeName) {
+  const db = await openIndexedDB();
+  const transaction = db.transaction(storeName, 'readonly');
+  const store = transaction.objectStore(storeName);
+  const request = store.get('fileHandles');
+  const result = await request.onsuccess;
+  return result.target.result;
+}
+
+Office.onReady(function (info) {
+  if (info.host === Office.HostType.Outlook) {
+    /*loadHandles().then(() => {
+      if (excelFileHandle) {
+        console.log("Excel file handle loaded successfully");
+      }
+      if (attachmentsFolderHandle) {
+        console.log("Attachment folder handle loaded successfully");
+      }
+    });*/
+//    loadFormDataFromRoaming();
+  }
+});