def embed_dicom_and_nifti_metadata(dcmfiles, niftifile, infofile, bids_info):
    """Embed metadata from nifti (affine etc) and dicoms into infofile (json)

    `niftifile` should exist. Its affine's orientation information is used while
    establishing new `NiftiImage` out of dicom stack and together with `bids_info`
    (if provided) is dumped into json `infofile`

    Parameters
    ----------
    dcmfiles
    niftifile
    infofile
    bids_info: dict
      Additional metadata to be embedded. `infofile` is overwritten if exists,
      so here you could pass some metadata which would overload (at the first
      level of the dict structure, no recursive fancy updates) what is obtained
      from nifti and dicoms

    """
    import nibabel as nb
    import os.path as op
    import json
    import re
    from heudiconv.utils import save_json
    from heudiconv.external.dcmstack import ds
    stack = ds.parse_and_stack(dcmfiles, force=True).values()
    if len(stack) > 1:
        raise ValueError('Found multiple series')
    stack = next(iter(stack))
    if not op.exists(niftifile):
        raise NotImplementedError(
            '%s does not exist. We are not producing new nifti files here any longer. Use dcm2niix directly or .convert.nipype_convert helper .'
             % niftifile)
    orig_nii = nb.load(niftifile)
    aff = orig_nii.affine
    ornt = nb.orientations.io_orientation(aff)
    axcodes = nb.orientations.ornt2axcodes(ornt)
    new_nii = stack.to_nifti(voxel_order=''.join(axcodes), embed_meta=True)
    meta_info = ds.NiftiWrapper(new_nii).meta_ext.to_json()
    meta_info = json.loads(meta_info)
    if bids_info:
        meta_info.update(bids_info)
    save_json(infofile, meta_info)
