class SpecPropertiesCustomizer implements GlobalOpenApiCustomizer {

	/**
	 * The Open api properties.
	 */
	private final OpenAPI openApiProperties;

	/**
	 * Instantiates a new Spec properties customizer.
	 *
	 * @param springDocConfigProperties the spring doc config properties
	 */
	public SpecPropertiesCustomizer(SpringDocConfigProperties springDocConfigProperties) {
		this.openApiProperties = springDocConfigProperties.getOpenApi();
	}

	/**
	 * Instantiates a new Spec properties customizer.
	 *
	 * @param openApiProperties the open api properties
	 */
	public SpecPropertiesCustomizer(OpenAPI openApiProperties) {
		this.openApiProperties = openApiProperties;
	}

	@Override
	public void customise(OpenAPI openApi) {
		customizeOpenApi(openApi, openApiProperties);
	}

	/**
	 * Customize open api.
	 *
	 * @param openApi           the open api
	 * @param openApiProperties the open api properties
	 */
	private void customizeOpenApi(OpenAPI openApi, OpenAPI openApiProperties) {
		if (openApiProperties != null) {
			Info infoProperties = openApiProperties.getInfo();
			if (infoProperties != null)
				customizeInfo(openApi, infoProperties);

			Components componentsProperties = openApiProperties.getComponents();
			if (componentsProperties != null)
				customizeComponents(openApi, componentsProperties);
			
			Paths pathsProperties = openApiProperties.getPaths();
			if (pathsProperties != null)
				customizePaths(openApi, pathsProperties);
		}
	}

	/**
	 * Customize paths.
	 *
	 * @param openApi         the open api
	 * @param pathsProperties the paths properties
	 */
	private void customizePaths(OpenAPI openApi, Paths pathsProperties) {<FILL_FUNCTION_BODY>}

	/**
	 * Customize components.
	 *
	 * @param openApi              the open api
	 * @param componentsProperties the components properties
	 */
	private void customizeComponents(OpenAPI openApi, Components componentsProperties) {
		Components components = openApi.getComponents();
		if (components == null || CollectionUtils.isEmpty(components.getSchemas())) {
			openApi.components(componentsProperties);
		}
		else {
			Map<String, Schema> schemaMap = components.getSchemas();
			schemaMap.forEach((key, schema) -> {
				Schema schemaProperties = componentsProperties.getSchemas().get(key);
				if (schemaProperties != null) {
					resolveString(schema::setDescription, schemaProperties::getDescription);
					Map<String, Schema> properties = schema.getProperties();
					if (CollectionUtils.isEmpty(properties)) {
						return;
					}
					properties.forEach((propKey, propSchema) -> {
						Schema propSchemaProperties = (Schema) schemaProperties.getProperties().get(propKey);
						if (propSchemaProperties != null) {
							resolveString(propSchema::description, propSchemaProperties::getDescription);
							resolveString(propSchema::title, propSchemaProperties::getTitle);
							resolveString(propSchema::example, propSchemaProperties::getExample);
						}
					});
				}
			});
		}
	}

	/**
	 * Customize info.
	 *
	 * @param openApi        the open api
	 * @param infoProperties the info properties
	 */
	private void customizeInfo(OpenAPI openApi, Info infoProperties) {
		Info info = openApi.getInfo();
		if (info != null) {
			resolveString(info::title, infoProperties::getTitle);
			resolveString(info::description, infoProperties::getDescription);
			resolveString(info::version, infoProperties::getVersion);
			resolveString(info::termsOfService, infoProperties::getTermsOfService);
			resolveString(info::summary, infoProperties::getSummary);

			License license = info.getLicense();
			License licenseProperties = infoProperties.getLicense();
			if (license != null) {
				resolveString(license::name, licenseProperties::getName);
				resolveString(license::url, licenseProperties::getUrl);
			}
			else
				info.license(licenseProperties);

			Contact contact = info.getContact();
			Contact contactProperties = infoProperties.getContact();
			if (contact != null) {
				resolveString(contact::name, contactProperties::getName);
				resolveString(contact::email, contactProperties::getEmail);
				resolveString(contact::url, contactProperties::getUrl);
			}
			else
				info.contact(contactProperties);
		}
		else
			openApi.info(infoProperties);
	}


	/**
	 * Resolve string.
	 *
	 * @param setter the setter
	 * @param getter the value
	 */
	private void resolveString(Consumer<String> setter, Supplier<Object> getter) {
		String value = (String) getter.get();
		if (StringUtils.isNotBlank(value)) {
			setter.accept(value);
		}
	}

	/**
	 * Resolve set.
	 *
	 * @param setter the setter
	 * @param getter the getter
	 */
	private void resolveSet(Consumer<List> setter, Supplier<List> getter) {
		List value =  getter.get();
		if (!CollectionUtils.isEmpty(value)) {
			setter.accept(value);
		}
	}


}

		Paths paths = openApi.getPaths();
		if (paths == null) {
			openApi.paths(pathsProperties);
		}
		else {
			paths.forEach((path, pathItem) -> {
				if (path.startsWith("/")) {
					path = path.substring(1); // Remove the leading '/'
				}
				PathItem pathItemProperties = pathsProperties.get(path);
				if (pathItemProperties != null) {
					resolveString(pathItem::description, pathItemProperties::getDescription);
					resolveString(pathItem::summary, pathItemProperties::getSummary);

					Map<HttpMethod, Operation>  operationMap = pathItem.readOperationsMap();
					Map<HttpMethod, Operation>  operationMapProperties = pathItemProperties.readOperationsMap();

					operationMapProperties.forEach((httpMethod, operationProperties) -> {
						Operation operationToCustomize = operationMap.get(httpMethod);
						if (operationToCustomize != null) {
							resolveString(operationToCustomize::description, operationProperties::getDescription);
							resolveString(operationToCustomize::summary, operationProperties::getSummary);
							resolveSet(operationToCustomize::tags, operationProperties::getTags);
						}
					});
				}});
		}
	
<no_super_class>