QDomDocument createDescribeCoverageDocument( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
      const QgsServerRequest &request )
  {
    Q_UNUSED( version );

    QDomDocument doc;

    QgsServerRequest::Parameters parameters = request.parameters();

#ifdef HAVE_SERVER_PYTHON_PLUGINS
    QgsAccessControl *accessControl = serverIface->accessControls();
#endif

    //wcs:WCS_Capabilities element
    QDomElement coveDescElement = doc.createElement( QStringLiteral( "CoverageDescription" )/*wcs:CoverageDescription*/ );
    coveDescElement.setAttribute( QStringLiteral( "xmlns" ), WCS_NAMESPACE );
    coveDescElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
    coveDescElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/describeCoverage.xsd" );
    coveDescElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
    coveDescElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
    coveDescElement.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0.0" ) );
    coveDescElement.setAttribute( QStringLiteral( "updateSequence" ), QStringLiteral( "0" ) );
    doc.appendChild( coveDescElement );

    //defining coverage name
    QString coveNames;
    //read COVERAGE
    QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "COVERAGE" ) );
    if ( cove_name_it != parameters.constEnd() )
    {
      coveNames = cove_name_it.value();
    }
    if ( coveNames.isEmpty() )
    {
      QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "IDENTIFIER" ) );
      if ( cove_name_it != parameters.constEnd() )
      {
        coveNames = cove_name_it.value();
      }
    }

    QStringList coveNameList;
    if ( !coveNames.isEmpty() )
    {
      coveNameList = coveNames.split( ',' );
      for ( int i = 0; i < coveNameList.size(); ++i )
      {
        coveNameList.replace( i, coveNameList.at( i ).trimmed() );
      }
    }

    QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project );
    for ( int i = 0; i < wcsLayersId.size(); ++i )
    {
      QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) );
      if ( !layer )
      {
        continue;
      }
      if ( layer->type() != QgsMapLayer::LayerType::RasterLayer )
      {
        continue;
      }
#ifdef HAVE_SERVER_PYTHON_PLUGINS
      if ( !accessControl->layerReadPermission( layer ) )
      {
        continue;
      }
#endif
      QString name = layer->name();
      if ( !layer->shortName().isEmpty() )
        name = layer->shortName();
      name = name.replace( ' ', '_' );

      if ( coveNameList.size() == 0 || coveNameList.contains( name ) )
      {
        QgsRasterLayer *rLayer = qobject_cast<QgsRasterLayer *>( layer );
        coveDescElement.appendChild( getCoverageOffering( doc, const_cast<QgsRasterLayer *>( rLayer ), project ) );
      }
    }
    return doc;
  }