function infotext = meshInfoText( m )
    infotext = '';
    % Write out the morphogen properties: diffusion, decay, and mutation.
    infotext = [ infotext, ...
                 char(10), ...
                 sprintf( '%% Mesh type: %s\n', m.meshparams.type ) ];
    f = sort( fieldnames( m.meshparams ) );
    ss = cell(1,length(f));
    for i=1:length(f)
        if ~strcmp( f{i}, 'type' )
            x = m.meshparams.(f{i});
            ss{i} = sprintf( '%% %15s: %s', f{i}, num2string( x ) );
        end
    end
    infotext = [ addstrings( infotext, ss ), char(10) ];

    nummgens = size( m.morphogens, 2 );
    conductivities = sum( m.absKvector( [1 2], : ), 1 )/2;
    if true || any( conductivities ) || any( m.mgen_absorption ) || any( m.mutantLevel ~= 1 )
        infotext = [ infotext, ...
                     sprintf( '%% %20s   Diffusion   Decay   Dilution   Mutant\n', 'Morphogen' ), ... 
                     sprintf( '%% %20s----------------------------------------\n', '---------' ) ];
        ss = cell( 1, nummgens );
        for i=1:nummgens
            c = conductivities(i);
            a = m.mgen_absorption(i);
            d = m.mgen_dilution(i);
            mu = m.mutantLevel(i);
            s1 = sprintf( '%% %20s  ', m.mgenIndexToName{i} );
            if c
                s2 = sprintf( '   %7.3g', c );
            else
                s2 = sprintf( '   %7s', '----' );
            end
            if a
                s3 = sprintf( ' %7.3g', a );
            else
                s3 = sprintf( ' %7s', '----' );
            end
            if d
                s4 = sprintf( ' %10s', 'yes' );
            else
                s4 = sprintf( ' %10s', '---' );
            end
            if mu ~= 1
                s5 = sprintf( '  %7.3g', mu );
            else
                s5 = sprintf( '  %7s', '----' );
            end
            ss{i} = [ s1, s2, s3, s4, s5 ];
        end
        infotext = addstrings( infotext, ss );
    end
    
    % Poisson's ratio
    infotext = [ infotext, ...
        sprintf( '%% Poisson''s ratio: %g.\n', m.globalProps.poissonsRatio ), ...
        sprintf( '%% Thickness params: rel %g, abs %g, areal %g, mode %c\n', ...
            m.globalProps.thicknessRelative, ...
            m.globalDynamicProps.thicknessAbsolute, ...
            m.globalProps.thicknessArea, ...
            m.globalProps.thicknessMode ), ...
        sprintf( '%% Negative growth allowed: %c\n', ...
            boolchar( m.globalProps.allowNegativeGrowth ) ), ...
        sprintf( '%% Minimum polarisation gradient %g.\n', ...
            m.globalProps.mingradient ), ...
        sprintf( '%% Time step %g %ss.\n', ...
            m.globalProps.timestep, ...
            m.globalProps.timeunitname ) ];
    
    if m.globalDynamicProps.locatenode > 0
        infotext = [ infotext, ...
            sprintf( '%% Node %d is fixed at [%g, %g, %g].\n', ...
                m.globalDynamicProps.locatenode, ...
                m.nodes(m.globalDynamicProps.locatenode,:) ) ];
    end
    
    if m.globalProps.maxFEcells==0
        infotext = [ infotext, ...
            sprintf( '%% Number of FEs is unlimited.\n' ) ];
    else
        infotext = [ infotext, ...
            sprintf( '%% Maximum number of FEs is %d.\n', ...
                m.globalProps.maxFEcells ) ];
    end
    
    infotext = [ infotext, ...
                 sprintf( '%% Long edges may%s be split.\n', ...
                     boolchar( m.globalProps.allowSplitLongFEM, '', ' not' ) ), ...
                 sprintf( '%% Edges may%s be split near a bend.\n', ...
                     boolchar( m.globalProps.allowSplitBentFEM, '', ' not' ) ) ];
    
    if m.globalProps.allowSplitBio
        if m.globalProps.bioAsplitcells
            infotext = [ infotext, ...
                 sprintf( '%% Biological cells may be split.\n' ) ];
        else
            infotext = [ infotext, ...
                 sprintf( '%% Biological cell splitting is faked by splitting the edges only.\n' ) ];
        end
    else
        infotext = [ infotext, ...
                 sprintf( '%% Biological cells may not be split.\n' ) ];
    end
    
    if m.globalProps.maxBioAcells==0
        infotext = [ infotext, ...
                 sprintf( '%% Number of biological cells is unlimited.\n' ) ];
    else
        infotext = [ infotext, ...
                 sprintf( '%% Maximum number of biological cells is %d.\n', ...
                    m.globalProps.maxBioAcells ) ];
    end
    
    infotext = [ infotext, ...
                sprintf( '%% Edge flipping is%s allowed.\n', ...
                    boolchar( m.globalProps.allowFlipEdges, '', ' not' ) ), ...
                sprintf( '%% Thin triangle elision is%s allowed.\n', ...
                    boolchar( m.globalProps.allowElideEdges, '', ' not' ) ), ...
                sprintf( '%% The mesh is%s constrained to be flat.\n', ...
                    boolchar( m.globalProps.alwaysFlat, '', ' not' ) ), ...
                sprintf( '%% Growth is %s.\n', ...
                    boolchar( m.globalProps.growthEnabled, 'enabled', 'disabled' ) ), ...
                sprintf( '%% Diffusion is %s.\n', ...
                    boolchar( m.globalProps.diffusionEnabled, 'enabled', 'disabled' ) ), ...
                sprintf( '%% Deformation is %s.\n', ...
                    boolchar( m.globalProps.plasticGrowth, 'plastic', 'elastic' ) ), ...
                sprintf( '%% The growth equations are solved by the %s method.\n', ...
                    m.globalProps.solver ), ...
                sprintf( '%% Solver tolerance for elasticity %g.\n', ...
                    m.globalProps.solvertolerance ), ...
                sprintf( '%% Solver tolerance for diffusion %g.\n', ...
                    m.globalProps.diffusiontolerance ), ...
                char(10) ];
end
