diff --git a/nipype/interfaces/spm/model.py b/nipype/interfaces/spm/model.py
index 4a55a4ea7..ddf35ef44 100644
--- a/nipype/interfaces/spm/model.py
+++ b/nipype/interfaces/spm/model.py
@@ -29,7 +29,7 @@ from ...utils.filemanip import (filename_to_list, list_to_filename,
 from ..base import (Bunch, traits, TraitedSpec, File, Directory,
                     OutputMultiPath, InputMultiPath, isdefined)
 from .base import (SPMCommand, SPMCommandInputSpec,
-                   scans_for_fnames)
+                   scans_for_fnames, ImageFileSPM)
 
 __docformat__ = 'restructuredtext'
 logger = logging.getLogger('interface')
@@ -179,27 +179,38 @@ class Level1Design(SPMCommand):
 
 class EstimateModelInputSpec(SPMCommandInputSpec):
     spm_mat_file = File(exists=True, field='spmmat',
-                        desc='absolute path to SPM.mat',
-                        copyfile=True,
-                        mandatory=True)
-    estimation_method = traits.Dict(traits.Enum('Classical', 'Bayesian2',
-                                                'Bayesian'),
-                                    field='method',
-                                    desc=('Classical, Bayesian2, '
-                                          'Bayesian (dict)'),
-                                    mandatory=True)
-    flags = traits.Str(desc='optional arguments (opt)')
+        copyfile=True, mandatory=True,
+        desc='Absolute path to SPM.mat')
+    estimation_method = traits.Dict(
+        traits.Enum('Classical', 'Bayesian2', 'Bayesian'),
+        field='method', mandatory=True,
+        desc=('Dictionary of either Classical: 1, Bayesian: 1, '
+              'or Bayesian2: 1 (dict)'))
+    write_residuals = traits.Bool(field='write_residuals',
+        desc="Write individual residual images")
+    flags = traits.Dict(desc='Additional arguments')
 
 
 class EstimateModelOutputSpec(TraitedSpec):
-    mask_image = File(exists=True,
-                      desc='binary mask to constrain estimation')
-    beta_images = OutputMultiPath(File(exists=True),
-                                  desc='design parameter estimates')
-    residual_image = File(exists=True,
-                          desc='Mean-squared image of the residuals')
-    RPVimage = File(exists=True, desc='Resels per voxel image')
+    mask_image = ImageFileSPM(exists=True,
+        desc='binary mask to constrain estimation')
+    beta_images = OutputMultiPath(ImageFileSPM(exists=True),
+        desc='design parameter estimates')
+    residual_image = ImageFileSPM(exists=True,
+        desc='Mean-squared image of the residuals')
+    residual_images = OutputMultiPath(ImageFileSPM(exists=True),
+        desc="individual residual images (requires `write_residuals`")
+    RPVimage = ImageFileSPM(exists=True, desc='Resels per voxel image')
     spm_mat_file = File(exists=True, desc='Updated SPM mat file')
+    labels = ImageFileSPM(exists=True, desc="label file")
+    SDerror = OutputMultiPath(ImageFileSPM(exists=True),
+        desc="Images of the standard deviation of the error")
+    ARcoef = OutputMultiPath(ImageFileSPM(exists=True),
+        desc="Images of the AR coefficient")
+    Cbetas = OutputMultiPath(ImageFileSPM(exists=True),
+        desc="Images of the parameter posteriors")
+    SDbetas = OutputMultiPath(ImageFileSPM(exists=True),
+        desc="Images of the standard deviation of parameter posteriors")
 
 
 class EstimateModel(SPMCommand):
@@ -211,6 +222,7 @@ class EstimateModel(SPMCommand):
     --------
     >>> est = EstimateModel()
     >>> est.inputs.spm_mat_file = 'SPM.mat'
+    >>> est.inputs.estimation_method = {'Classical': 1}
     >>> est.run() # doctest: +SKIP
     """
     input_spec = EstimateModelInputSpec
@@ -225,7 +237,7 @@ class EstimateModel(SPMCommand):
             return np.array([str(val)], dtype=object)
         if opt == 'estimation_method':
             if isinstance(val, (str, bytes)):
-                return {'%s' % val: 1}
+                return {'{}'.format(val): 1}
             else:
                 return val
         return super(EstimateModel, self)._format_arg(opt, spec, val)
@@ -235,36 +247,43 @@ class EstimateModel(SPMCommand):
         """
         einputs = super(EstimateModel, self)._parse_inputs(skip=('flags'))
         if isdefined(self.inputs.flags):
-            einputs[0].update(self.inputs.flags)
+            einputs[0].update({flag: val for (flag, val) in
+                               self.inputs.flags.items()})
         return einputs
 
     def _list_outputs(self):
         outputs = self._outputs().get()
-        pth, _ = os.path.split(self.inputs.spm_mat_file)
-        spm12 = '12' in self.version.split('.')[0]
-        if spm12:
-            mask = os.path.join(pth, 'mask.nii')
-        else:
-            mask = os.path.join(pth, 'mask.img')
-        outputs['mask_image'] = mask
+        pth = os.path.dirname(self.inputs.spm_mat_file)
+        outtype = 'nii' if '12' in self.version.split('.')[0] else 'img'
         spm = sio.loadmat(self.inputs.spm_mat_file, struct_as_record=False)
-        betas = []
-        for vbeta in spm['SPM'][0, 0].Vbeta[0]:
-            betas.append(str(os.path.join(pth, vbeta.fname[0])))
-        if betas:
-            outputs['beta_images'] = betas
-        if spm12:
-            resms = os.path.join(pth, 'ResMS.nii')
-        else:
-            resms = os.path.join(pth, 'ResMS.img')
-        outputs['residual_image'] = resms
-        if spm12:
-            rpv = os.path.join(pth, 'RPV.nii')
-        else:
-            rpv = os.path.join(pth, 'RPV.img')
-        outputs['RPVimage'] = rpv
-        spm = os.path.join(pth, 'SPM.mat')
-        outputs['spm_mat_file'] = spm
+
+        betas = [vbeta.fname[0] for vbeta in spm['SPM'][0, 0].Vbeta[0]]
+        if ('Bayesian' in self.inputs.estimation_method.keys() or
+            'Bayesian2' in self.inputs.estimation_method.keys()):
+            outputs['labels'] = os.path.join(pth,
+                                            'labels.{}'.format(outtype))
+            outputs['SDerror'] = glob(os.path.join(pth, 'Sess*_SDerror*'))
+            outputs['ARcoef'] = glob(os.path.join(pth, 'Sess*_AR_*'))
+            if betas:
+                outputs['Cbetas'] = [os.path.join(pth, 'C{}'.format(beta))
+                                            for beta in betas]
+                outputs['SDbetas'] = [os.path.join(pth, 'SD{}'.format(beta))
+                                            for beta in betas]
+
+        if 'Classical' in self.inputs.estimation_method.keys():
+            outputs['residual_image'] = os.path.join(pth,
+                                            'ResMS.{}'.format(outtype))
+            outputs['RPVimage'] =  os.path.join(pth,
+                                            'RPV.{}'.format(outtype))
+            if self.inputs.write_residuals:
+                outputs['residual_images'] = glob(os.path.join(pth, 'Res_*'))
+            if betas:
+                outputs['beta_images'] = [os.path.join(pth, beta)
+                                            for beta in betas]
+
+        outputs['mask_image'] = os.path.join(pth,
+                                            'mask.{}'.format(outtype))
+        outputs['spm_mat_file'] = os.path.join(pth, 'SPM.mat')
         return outputs
 
 

spm.EstimateModel additional args broken
### Summary
Issue brought up on [Neurostars#436](https://neurostars.org/t/nipype-interfaces-without-options-present-in-the-underlying-executable-function/436)
### Actual behavior
`EstimateModel` expects a string for input `flags`, but later expects a dictionary.
### Expected behavior
Additional inputs can be added.
### Platform details:

Please paste the output of: `python -c "import nipype; print(nipype.get_info()); print(nipype.__version__)"`
```
{'pkg_path': '/code/nipype/nipype', 'commit_source': 'repository', 'commit_hash': '71e2140', 'nipype_version': '1.0.0-g71e2140.dev', 'sys_version': '3.6.1 | packaged by conda-forge | (default, Mar 23 2017, 21:05:12) \n[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)]', 'sys_executable': '/home/mathias/miniconda2/envs/dev3/bin/python', 'sys_platform': 'linux', 'numpy_version': '1.12.1', 'scipy_version': '0.19.0', 'networkx_version': '1.11', 'nibabel_version': '2.1.0', 'traits_version': '4.6.0'}
1.0.0-g71e2140.dev
```
### Execution environment
Local

Addressing this now
diff --git a/nipype/interfaces/spm/tests/test_auto_EstimateModel.py b/nipype/interfaces/spm/tests/test_auto_EstimateModel.py
index c99ff7dd0..703c97c6f 100644
--- a/nipype/interfaces/spm/tests/test_auto_EstimateModel.py
+++ b/nipype/interfaces/spm/tests/test_auto_EstimateModel.py
@@ -23,6 +23,8 @@ def test_EstimateModel_inputs():
     use_v8struct=dict(min_ver='8',
     usedefault=True,
     ),
+    write_residuals=dict(field='write_residuals',
+    ),
     )
     inputs = EstimateModel.input_spec()
 
@@ -32,10 +34,16 @@ def test_EstimateModel_inputs():
 
 
 def test_EstimateModel_outputs():
-    output_map = dict(RPVimage=dict(),
+    output_map = dict(ARcoef=dict(),
+    Cbetas=dict(),
+    RPVimage=dict(),
+    SDbetas=dict(),
+    SDerror=dict(),
     beta_images=dict(),
+    labels=dict(),
     mask_image=dict(),
     residual_image=dict(),
+    residual_images=dict(),
     spm_mat_file=dict(),
     )
     outputs = EstimateModel.output_spec()

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2021.5.30
click==8.0.4
configparser==5.2.0
decorator==4.4.2
funcsigs==1.0.2
future==1.0.0
importlib-metadata==4.8.3
iniconfig==1.1.1
isodate==0.6.1
lxml==5.3.1
mock==5.2.0
networkx==2.5.1
nibabel==3.2.2
-e git+https://github.com/nipy/nipype.git@cda3fdc3be231f2c9d7bdbdbadee472a0bad9e92#egg=nipype
numpy==1.19.5
packaging==21.3
pluggy==1.0.0
prov==2.0.1
py==1.11.0
pydotplus==2.0.2
pyparsing==3.1.4
pytest==7.0.1
python-dateutil==2.9.0.post0
rdflib==5.0.0
scipy==1.5.4
simplejson==3.20.1
six==1.17.0
tomli==1.2.3
traits==6.4.1
typing_extensions==4.1.1
zipp==3.6.0

name: nipype
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - click==8.0.4
      - configparser==5.2.0
      - decorator==4.4.2
      - funcsigs==1.0.2
      - future==1.0.0
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - isodate==0.6.1
      - lxml==5.3.1
      - mock==5.2.0
      - networkx==2.5.1
      - nibabel==3.2.2
      - numpy==1.19.5
      - packaging==21.3
      - pluggy==1.0.0
      - prov==2.0.1
      - py==1.11.0
      - pydotplus==2.0.2
      - pyparsing==3.1.4
      - pytest==7.0.1
      - python-dateutil==2.9.0.post0
      - rdflib==5.0.0
      - scipy==1.5.4
      - simplejson==3.20.1
      - six==1.17.0
      - tomli==1.2.3
      - traits==6.4.1
      - typing-extensions==4.1.1
      - zipp==3.6.0
prefix: /opt/conda/envs/nipype

nipype/interfaces/spm/tests/test_auto_EstimateModel.py::test_EstimateModel_inputs
nipype/interfaces/spm/tests/test_auto_EstimateModel.py::test_EstimateModel_outputs
nipype/interfaces/spm/model.py
nipype/interfaces/spm/model.py