diff --git a/src/Form/FillPdfFormForm.php b/src/Form/FillPdfFormForm.php
index 832958abd5acbce3a321108b01c7718c97fa3a13..806551af15925f951d3cd465a0e5e05b5a919fcb 100644
--- a/src/Form/FillPdfFormForm.php
+++ b/src/Form/FillPdfFormForm.php
@@ -420,44 +420,42 @@ class FillPdfFormForm extends ContentEntityForm {
     /** @var \Drupal\fillpdf\FillPdfFormInterface $entity */
     $entity = $this->getEntity();
 
-    $message = [];
-    $message[] = $this->t('FillPDF Form %link has been updated.', ['%link' => $entity->toLink()->toString()]);
+    $this->messenger()->addStatus($this->t('FillPDF Form %link has been updated.', ['%link' => $entity->toLink()->toString()]));
 
     if ($form_state->getValue('upload_pdf')) {
+      $existing_fields = $entity->getFormFields();
+
       /** @var \Drupal\file\FileInterface $new_file */
       $new_file = File::load($form_state->getValue('upload_pdf')['0']);
+      $new_file->setPermanent();
+      $new_file->save();
 
-      $existing_fields = $entity->getFormFields();
+      // Set the new file to our unsaved FillPdf form and parse its fields.
+      $entity->file = $new_file;
+      $new_fields = $this->inputHelper->parseFields($entity);
 
-      // Delete existing fields.
-      /** @var \Drupal\fillpdf\FillPdfFormFieldInterface $existing_field */
-      foreach ($existing_fields as $existing_field) {
-        $existing_field->delete();
+      // Save new fields, delete existing ones.
+      foreach ($new_fields as $field) {
+        $field->save();
       }
-
-      $added = $this->inputHelper->attachPdfToForm($new_file, $entity);
-
-      $form_fields = $added['fields'];
-
-      $message[] = $this->t('Your previous field mappings have been transferred to the new PDF template you uploaded.');
-
-      // Import previous form field values over new fields.
-      $non_matching_fields = $this->serializer->importFormFields($existing_fields, $form_fields);
-      if (count($non_matching_fields)) {
-        $message[] = $this->t("These keys couldn't be found in the new PDF:");
+      foreach ($existing_fields as $field) {
+        $field->delete();
       }
 
-      $this->messenger()->addStatus(implode(' ', $message));
+      $non_matching_fields = array_diff_key($existing_fields, $new_fields);
 
-      foreach ($non_matching_fields as $non_matching_field) {
-        $this->messenger()->addWarning($non_matching_field);
+      if (count($existing_fields) > count($non_matching_fields)) {
+        $this->messenger()->addStatus($this->t('Your previous field mappings have been transferred to the new PDF template you uploaded.'));
+      }
+      if (count($non_matching_fields)) {
+        $this->messenger()->addWarning($this->t("These keys couldn't be found in the new PDF:"));
+        foreach (array_keys($non_matching_fields) as $pdf_key) {
+          $this->messenger()->addWarning($pdf_key);
+        }
       }
 
       $this->messenger()->addStatus($this->t('You might also want to update the <em>Filename pattern</em> field; this has not been changed.'));
     }
-    else {
-      $this->messenger()->addStatus(reset($message));
-    }
 
     // Save custom form elements' values, resetting default_entity_id to NULL,
     // if not matching the default entity type.
diff --git a/src/InputHelper.php b/src/InputHelper.php
index 17dc3c55196b845854cfc2c2ba069bbfd33a6bb0..da7bbd19390bf85beaf81d237b3b0c9ba98db2d7 100644
--- a/src/InputHelper.php
+++ b/src/InputHelper.php
@@ -42,17 +42,12 @@ class InputHelper implements InputHelperInterface {
   }
 
   /**
-   * Attaches a PDF template file to a FillPdfForm.
-   *
-   * @param \Drupal\file\FileInterface $file
-   *   The PDF template file to attach.
-   * @param \Drupal\fillpdf\FillPdfFormInterface $existing_form
-   *   The FillPdfForm the PDF template file should be attached to.
-   *
-   * @return array
+   * {@inheritdoc}
    */
   public function attachPdfToForm(FileInterface $file, FillPdfFormInterface $existing_form = NULL) {
-    $this->saveFileUpload($file);
+    // Save the file so we can get an fid.
+    $file->setPermanent();
+    $file->save();
 
     if ($existing_form) {
       $fillpdf_form = $existing_form;
@@ -68,7 +63,26 @@ class InputHelper implements InputHelperInterface {
     // Save PDF configuration before parsing.
     $fillpdf_form->save();
 
-    $config = $this->config('fillpdf.settings');
+    // Parse and save fields.
+    $form_fields = $this->parseFields($fillpdf_form);
+    foreach ($form_fields as $field) {
+      $field->save();
+    }
+
+    return ['form' => $fillpdf_form, 'fields' => $form_fields];
+  }
+
+  /**
+   * Parses fields of a FillPDF form.
+   *
+   * @param \Drupal\fillpdf\FillPdfFormInterface $fillpdf_form
+   *   The FillPdfForm the PDF template file should be attached to.
+   *
+   * @return \Drupal\fillpdf\FillPdfFormFieldInterface[]
+   *   Associative array of FillPdfFormField objects keyed by the PDF key.
+   */
+  public function parseFields(FillPdfFormInterface $fillpdf_form) {
+    $config = $this->configManager->get('fillpdf.settings');
     $fillpdf_service = $config->get('backend');
     /** @var FillPdfBackendPluginInterface $backend */
     $backend = $this->backendManager->createInstance($fillpdf_service, $config->get());
@@ -78,8 +92,8 @@ class InputHelper implements InputHelperInterface {
 
     $form_fields = [];
     foreach ((array) $fields as $arr) {
+      // Don't store "container" fields.
       if ($arr['type']) {
-        // Don't store "container" fields.
         // pdftk sometimes inserts random &#0; markers - strip these out.
         // NOTE: This may break forms that actually DO contain this pattern,
         // but 99%-of-the-time functionality is better than merge failing due
@@ -97,14 +111,7 @@ class InputHelper implements InputHelperInterface {
         $form_fields[$arr['name']] = $field;
       }
     }
-
-    // Save the fields that were parsed out (if any). If none were, set a
-    // warning message telling the user that.
-    foreach ($form_fields as $fillpdf_form_field) {
-      /** @var \Drupal\fillpdf\Entity\FillPdfFormField $fillpdf_form_field */
-      $fillpdf_form_field->save();
-    }
-    return ['form' => $fillpdf_form, 'fields' => $form_fields];
+    return $form_fields;
   }
 
   /**
@@ -112,26 +119,16 @@ class InputHelper implements InputHelperInterface {
    *
    * @param \Drupal\file\FileInterface $file
    *   The file object to save.
+   *
+   * @deprecated in fillpdf:8.x-4.7 and will be removed from fillpdf:8.x-5.0.
+   *   Use FileInterface::setPermanent() and FileInterface::save() instead.
+   * @see https://www.drupal.org/project/fillpdf/issues/3055123
+   * @see \Drupal\file\FileInterface
    */
   protected function saveFileUpload(FileInterface $file) {
-    // Save the file to get an fid, and then create a FillPdfForm record
-    // based off that.
+    @trigger_error('InputHelper::saveFileUpload() is deprecated in fillpdf:8.x-4.7 and will be removed before fillpdf:8.x-5.0. Use \Drupal\file\FileInterface::setPermanent() and \Drupal\file\FileInterface::save() instead. See https://www.drupal.org/project/fillpdf/issues/3055123.', E_USER_DEPRECATED);
     $file->setPermanent();
-    // Save the file so we can get an fid.
     $file->save();
   }
 
-  /**
-   * Returns an immutable configuration object for a given name.
-   *
-   * @param string $name
-   *   The name of the configuration object.
-   *
-   * @return \Drupal\Core\Config\ImmutableConfig
-   *   An immutable configuration object.
-   */
-  protected function config($name) {
-    return $this->configManager->get($name);
-  }
-
 }
diff --git a/src/InputHelperInterface.php b/src/InputHelperInterface.php
index 326fc3656c4a2ee71a9a82e48f13ab1414e98a1c..60b263699f1346ee4aab0b42c62aedc4f35465e8 100644
--- a/src/InputHelperInterface.php
+++ b/src/InputHelperInterface.php
@@ -11,6 +11,20 @@ use Drupal\file\FileInterface;
  */
 interface InputHelperInterface {
 
+  /**
+   * Attaches a PDF template file to a FillPdfForm.
+   *
+   * @param \Drupal\file\FileInterface $file
+   *   The PDF template file to attach.
+   * @param \Drupal\fillpdf\FillPdfFormInterface $existing_form
+   *   The FillPdfForm the PDF template file should be attached to.
+   *
+   * @return array
+   *   Associative array with the following keys:
+   *   - 'form': The updated FillPdfForm entity.
+   *   - 'fields': Associative array of the FillPdfForm entity's saved
+   *     FillPdfFormFields.
+   */
   public function attachPdfToForm(FileInterface $file, FillPdfFormInterface $existing_form = NULL);
 
 }
diff --git a/src/Serializer.php b/src/Serializer.php
index 002e3964e4ac1a246ba5f0e3afa13b73154a4c74..cbe99390aa7c0b7b844c2015984e2665a8110baa 100644
--- a/src/Serializer.php
+++ b/src/Serializer.php
@@ -99,26 +99,19 @@ class Serializer implements SerializerInterface {
   /**
    * {@inheritdoc}
    */
-  public function importFormFields(array $keyed_fields, array $existing_fields = []) {
-    $existing_fields_by_key = [];
-    foreach ($existing_fields as $pdf_key => $existing_field) {
-      $existing_fields_by_key[$pdf_key] = $existing_field;
-    }
-
-    $existing_field_pdf_keys = array_keys($existing_fields_by_key);
+  public function importFormFields(array $imported_fields, array $existing_fields = []) {
     $unmatched_pdf_keys = [];
-
-    foreach ($keyed_fields as $pdf_key => $keyed_field) {
+    foreach ($imported_fields as $pdf_key => $keyed_field) {
       // If the imported field's PDF key matching the PDF key of the
       // existing field, then copy the constituent entity properties.
-      if (in_array($pdf_key, $existing_field_pdf_keys, TRUE)) {
+      if (in_array($pdf_key, array_keys($existing_fields), TRUE)) {
         $properties_to_import = $keyed_field->getPropertiesToExport();
         foreach ($keyed_field->getFields() as $keyed_field_name => $keyed_field_data) {
           if (in_array($keyed_field_name, $properties_to_import, TRUE)) {
-            $existing_fields_by_key[$pdf_key]->{$keyed_field_name} = $keyed_field_data;
+            $existing_fields[$pdf_key]->{$keyed_field_name} = $keyed_field_data;
           }
         }
-        $existing_fields_by_key[$pdf_key]->save();
+        $existing_fields[$pdf_key]->save();
       }
       else {
         $unmatched_pdf_keys[] = $pdf_key;
@@ -145,7 +138,7 @@ class Serializer implements SerializerInterface {
    * @see \Drupal\fillpdf\SerializerInterface::importFormFields()
    */
   public function importFormFieldsByKey(array $form_fields, array $existing_fields = []) {
-    @trigger_error('SerializerInterface::importFormFieldsByKey() is deprecated in fillpdf:8.x-4.7 and will be removed before fillpdf:8.x-5.0. Use \Drupal\fillpdf\SerializerInterface::importFormFields() instead. See https://www.drupal.org/project/fillpdf/issues/3055097.', E_USER_DEPRECATED);
+    @trigger_error('SerializerInterface::importFormFieldsByKey() is deprecated in fillpdf:8.x-4.7 and will be removed before fillpdf:8.x-5.0. Use \Drupal\fillpdf\SerializerInterface::importFormFields() instead. See https://www.drupal.org/project/fillpdf/issues/3055097', E_USER_DEPRECATED);
     $keyed_fields = [];
     foreach ($form_fields as $form_field) {
       $keyed_fields[$form_field->pdf_key->value] = $form_field;