diff --git a/pom.xml b/pom.xml
index 6f0b0c4e6e383d517ef0a299c407435691b9b9f6..9b75880ce02ad79e5f6a73e162b3bdbdf015bcdc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -126,6 +126,12 @@
 			<version>2.10.1</version>
 		</dependency>
 
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+			<version>2.10.1</version>
+		</dependency>
+
 		<dependency>
 			<!-- see Porcelain https://git-scm.com/book/uz/v2/Appendix-B%3A-Embedding-Git-in-your-Applications-JGit -->
 			<groupId>org.eclipse.jgit</groupId>
diff --git a/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_4_6_Checker.java b/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_4_6_Checker.java
index 27c8748821b304407ec202a9e27798ade91d9fde..53900596c66fda841e2ec17a303d87c51b873e55 100644
--- a/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_4_6_Checker.java
+++ b/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_4_6_Checker.java
@@ -25,95 +25,33 @@
  */
 package fr.mines_stetienne.ci.saref.checkers;
 
+import java.io.File;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
 import java.net.http.HttpResponse;
+import java.nio.file.Files;
+import java.util.stream.Collectors;
 
-import org.apache.jena.rdf.model.Model;
-import org.apache.jena.rdf.model.ResIterator;
-import org.apache.jena.rdf.model.Resource;
-import org.apache.jena.vocabulary.DCTypes;
-import org.apache.jena.vocabulary.RDF;
-
-import fr.mines_stetienne.ci.saref.SAREF;
 import fr.mines_stetienne.ci.saref.SAREFPipelineException;
-import fr.mines_stetienne.ci.saref.entities.SAREFExample;
-//import fr.mines_stetienne.ci.saref.entities.SAREFVersion;
-import fr.mines_stetienne.ci.saref.entities.SAREFVersionName;
 import fr.mines_stetienne.ci.saref.managers.RepositoryManager;
-import fr.mines_stetienne.ci.saref.vocabs.SHACL;
 import fr.mines_stetienne.ci.saref.managers.ShaclValidationManager;
+import fr.mines_stetienne.ci.saref.utils.Languages;
+import org.semanticweb.owlapi.model.OWLOntology;
 
 /**
  * Checks TS 103 673 Clause 9.4.6: Conformance to reference ontology patterns.
  * The ontology in the ontology document of a SAREF project version shall conform to the SHACL specification of each
  * reference ontology pattern defined in this SAREF project version.
  */
-public class Clause_9_4_6_Checker extends AbstractShaclChecker {
+public class Clause_9_4_6_Checker extends AbstractClauseChecker {
 
-	private enum MESSAGE implements MessageResource {
-		dataset, conformsTo1, conformsToNot, conformsToNot2, conformsTo2, conformsTo3,
-		title1, title2, title3, abstract1, description1, description2,
-		license, ioexception
+	private enum MESSAGE {
+		one, missing, ioexception, server_unavailable
 	}
 
-	private final SAREFExample example = null;
-
-	public Clause_9_4_6_Checker(RepositoryManager repositoryManager) //, SAREFExample shacl
-			throws SAREFPipelineException {
-		super(repositoryManager, Clause_9_4_6_Checker.class);	// , "example " + example.getName());
-		//this.example = shacl;
-	}
-
-	@Override
-	protected Model getModel() {
-		Model model = example.getModel();
-		final String defaultVersion = "v0.0.1";
-		final String regex = "^" + example.getIRI().replace(defaultVersion, SAREF.REGEX_VERSION_NUMBER) + "$";
-		int onto = 0;
-		boolean found = false;
-		for (ResIterator it = model.listSubjectsWithProperty(RDF.type,  DCTypes.Dataset); it.hasNext();) {
-			Resource r = it.next();
-			if(versionName.equals(SAREFVersionName.DEFAULT)) {
-				if(r.getURI().matches(regex)) {
-					found = true;
-				}				
-			} else {
-				if(r.getURI().equals( example.getIRI() )) {
-					found = true;
-				}				
-			}
-			onto++;
-		}
-		if (onto != 1 || !found) {
-			final String msg;
-			if(versionName.equals(SAREFVersionName.DEFAULT)) {
-				msg = getMessage(MESSAGE.dataset, example.getIRI()).replace("v0.0.1", "<<some SAREF version name>>");
-			} else {
-				msg = getMessage(MESSAGE.dataset, example.getIRI());
-			}
-			logError(msg);
-		}	
-		return model;
-	}
-
-	protected final void updateShapeModel() {
-		if(!versionName.equals(SAREFVersionName.DEFAULT)) {
-			shapeModel.add(MESSAGE.conformsToNot.asResource(), SHACL.pattern, exactly(version.getIRI()));
-			add(MESSAGE.conformsTo1, version.getIRI());
-		}
-		add(MESSAGE.conformsTo2);
-		add(MESSAGE.conformsTo3);
-		add(MESSAGE.title1);
-		add(MESSAGE.title2);
-		add(MESSAGE.title3);
-		add(MESSAGE.abstract1);
-		add(MESSAGE.description1);
-		add(MESSAGE.description2);
-		add(exactly(SAREF.LICENSE), MESSAGE.license);
-		
-		if(versionName.equals(SAREFVersionName.DEFAULT)) {
-			remove(MESSAGE.conformsTo1);
-		}
+	public Clause_9_4_6_Checker(RepositoryManager repositoryManager) throws SAREFPipelineException {
+		super(repositoryManager, Clause_9_4_6_Checker.class);
 	}
 
 	/**
@@ -124,13 +62,49 @@ public class Clause_9_4_6_Checker extends AbstractShaclChecker {
 	 reference ontology pattern defined in this other SAREF project version.
 	 This method calls the generic docker image that runs a specific shacl files.
 	 * */
-	protected final void validateOntologyPerShacl(String ontologyToValidate, String shaclFile) {
-		//<<< process every file
+	@Override
+	public void checkClause() throws SAREFPipelineException {
+		OWLOntology ontology = pipeline.getOntologyManager().loadOntology(version, errorLogger);
+		if (ontology == null) {
+			return;
+		}
+		File dir = new File(repository.getDirectory(), "ontology");
+		File file = new File(dir, repository.getProject().getOntologyFileName(Languages.TEXT_TURTLE));
+		String ontologyToValidate = file.getAbsolutePath();
+
+		// First get the available directories. If none, not a problem.
+		File dir2 = new File(repository.getDirectory(), "patterns");
+		String[] directoryList = new String[]{};
 		try {
-			HttpResponse<String> response = new ShaclValidationManager(ontologyToValidate).validateOntologyWithShacl(shaclFile);
-		} catch (IOException | InterruptedException e) {
-			logError(getMessage(Clause_9_4_6_Checker.MESSAGE.ioexception));
+			String directories = Files.walk(dir2.toPath()).filter(p -> {
+				try {
+					return p.toFile().isDirectory() && !Files.isSameFile(dir2.toPath(), p);
+				} catch(IOException ex) {
+					return false;
+				}
+			}).map(p -> p.toString()).collect(Collectors.joining(", "));
+			if (directories.isEmpty()) {
+				return; // no SHACL directories found.
+			}
+			directoryList = directories.split(",");
+		} catch (IOException e) {
+			logError(getMessage(Clause_9_4_6_Checker.MESSAGE.ioexception), e);
 		}
-	}
 
+		ShaclValidationManager.PingValidationServer();
+
+		Map<String, HttpResponse<String>> responseMap = new HashMap<String, HttpResponse<String>>();
+		// process every shapes.ttl file in the sub-directories of the patterns directory.
+		for(int i = 0; i < directoryList.length; i++) {
+			String shaclFileName = directoryList[i] + "/shapes.ttl";  // "file://" +
+			try {
+				HttpResponse<String> response = new ShaclValidationManager(ontologyToValidate).validateOntologyWithShacl(shaclFileName);
+				System.out.println(response); //<<<
+				responseMap.put(shaclFileName, response);	//<<< parse map for errors
+			} catch (IOException | InterruptedException e) {
+				logError(getMessage(Clause_9_4_6_Checker.MESSAGE.ioexception, shaclFileName));
+			}
+		}
+		//System.out.println(responseMap); //<<<
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_4_Checker.java b/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_4_Checker.java
index 868cf6e5814a8037649807e3ac519b4841e9671a..c9e3232537c7a1fb966e599e1540e42255822502 100644
--- a/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_4_Checker.java
+++ b/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_4_Checker.java
@@ -29,6 +29,7 @@ import java.io.File;
 
 import fr.mines_stetienne.ci.saref.SAREFPipelineException;
 import fr.mines_stetienne.ci.saref.managers.RepositoryManager;
+import fr.mines_stetienne.ci.saref.utils.Languages;
 
 /**
  * Checks TS 103 673 Clause 9.4: The Ontology specification
diff --git a/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_8_1_Checker.java b/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_8_1_Checker.java
index 1f92aa98c8716c6bace4a94a82ae4a5e562d82ba..6cf183b99313634e50ab66687ee39eebd31054fe 100644
--- a/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_8_1_Checker.java
+++ b/src/main/java/fr/mines_stetienne/ci/saref/checkers/Clause_9_8_1_Checker.java
@@ -66,7 +66,7 @@ public class Clause_9_8_1_Checker extends AbstractClauseChecker {
 		}
 
 		// Step 4. Fetch the list of turtle files in the vocabularies directory.
-		File[] fileList = null;
+		File[] fileList = new File[]{};
 		try {
 			if (Files.walk(dir.toPath(), 1).filter(p -> !p.toFile().isFile() && !p.toFile().getName().startsWith("."))
 					.count() != 1) {
@@ -89,7 +89,7 @@ public class Clause_9_8_1_Checker extends AbstractClauseChecker {
 			return;
 		}
 
-		// <<< Step 6. Match each imports statements to the presence of each file using the last tag (e.g. "properties" +".ttl")
+		// TODO: Step 6. Match each imports statements to the presence of each file using the last tag (e.g. "properties" +".ttl")
 		//		Ignore turtle files which do not have a corresponding imports statements.
 		/*Iterator<OWLImportsDeclaration> itr = this.importDeclarations.iterator();
 		while(itr.hasNext()) { // <https://saref.etsi.org/saref4auto/v2.1.1/properties/>
diff --git a/src/main/java/fr/mines_stetienne/ci/saref/managers/ShaclValidationManager.java b/src/main/java/fr/mines_stetienne/ci/saref/managers/ShaclValidationManager.java
index 142ca7e6f66ed5d6cccc21d102a590bbcbf08392..1bb641c6a37aa766e94d1ba997f827cefb04f6a3 100644
--- a/src/main/java/fr/mines_stetienne/ci/saref/managers/ShaclValidationManager.java
+++ b/src/main/java/fr/mines_stetienne/ci/saref/managers/ShaclValidationManager.java
@@ -26,86 +26,101 @@
 package fr.mines_stetienne.ci.saref.managers;
 
 import java.io.IOException;
+import java.net.HttpURLConnection;
 import java.net.URI;
+import java.net.URL;
 import java.net.URLEncoder;
 import java.net.http.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Base64;
 
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
 import com.fasterxml.jackson.databind.ObjectMapper;
-//import fr.mines_stetienne.ci.saref.SAREFErrorLogger;
+import fr.mines_stetienne.ci.saref.SAREFPipelineException;
 
-/*
+/*	docker run -d --name SAREFvalidator -p 8080:8080 isaitb/shacl-validator	 # runs the generic validator.
 	Docs for RDF validator: https://www.itb.ec.europa.eu/docs/guides/latest/validatingRDF/index.html
-	Base docker image: https://hub.docker.com/r/isaitb/shacl-validator
+	Base docker image: https://hub.docker.com/r/isaitb/shacl-validator  (generic validator)
 	Use Swagger UI for testing: http://localhost:8080/shacl/swagger-ui/index.html#/{domain}/api/validate
 	BASE64 Encoder/Decoder: https://www.base64encode.org/
-    docker run -d --name SAREFvalidator -p 8080:8080 local/ontologyvalidator    # this runs the general validator.
 * */
 public class ShaclValidationManager {
 
-	private final static String BASE_URL = "http://localhost:8080/shacl/";  // <<<
+	private static String VALIDATOR_URL = "http://localhost:8080/shacl/";
 	private String ontologyToValidate;	// file:///home/davidgnabasik/dev/real_saref4auto/ontology/saref4auto.ttl or URL
-	private final HttpClient client;
-	private final ObjectMapper objectMapper;
+	private HttpClient client;
+	private ObjectMapper objectMapper;
+
+	//private String shaclRequestBody =
+	//		"{ \"contentToValidate\": \"ONTOLOGY_AS_BASE64_STRING\", \"embeddingMethod\": \"BASE64\", \"contentSyntax\": \"text/turtle\", \"reportSyntax\": \"application/json\", \"locale\": \"en\", \"rdfReportSyntax\": \"application/json\", \"externalRules\": [ { \"ruleSet\": \"SHACL_AS_BASE64_STRING\", \"embeddingMethod\": \"BASE64\", \"ruleSyntax\": \"text/turtle\" } ] }";
 
-	private static String encode(Object obj) {
+	private static String encodeBody(Object obj) {
 		return URLEncoder.encode(obj.toString(), StandardCharsets.UTF_8);
 	}
 
-	private enum MESSAGE {
+	private enum MESSAGE {	// each of these accepts a single string parameter.
 		http_exception, ioexception
 	}
 
-	// The full list of available tags: https://www.itb.ec.europa.eu/docs/guides/latest/validatingRDF/
-	// Replace default values for {contentToValidate, validationType}
-	private String shaclRequestBody = "{ "+	// generic validator option
-		"'contentToValidate': 'RDF_CONTENT_AS_BASE64_ENCODED_STRING', "+	// entire content of ontology file (or URI)
-		"'embeddingMethod': 'BASE64', "+  	// {STRING,URL,BASE64}
-		"'contentSyntax': 'text/turtle', "+
-		"'validationType': 'string', "+
-		"'reportSyntax': 'application/json', "+
-		"'locale': 'en', "+
-		"'rdfReportSyntax': 'application/json' "+
-		"}";
-					/* "contentToValidate": "",
-				"contentSyntax": "text/turtle",
-				"embeddingMethod": "BASE64",
-				"validationType": "Clause_9_4_3_1",
-				"reportSyntax": "application/json",
-				"locale": "en" */
-
-	JsonObject jsonObject = new JsonParser().parse(shaclRequestBody).getAsJsonObject();
-
 	/**
 	 * Open a REST interface to the SHACL validator.
 	 */
 	public ShaclValidationManager(String ontologyToValidate) throws IOException {
 		client = HttpClient.newHttpClient();
 		objectMapper = new ObjectMapper();
-		this.ontologyToValidate = ontologyToValidate;	//<<< test for ontology file presence.
+		this.ontologyToValidate = ontologyToValidate;
+		String url = System.getenv("VALIDATOR_URL");
+		if (url != null)  VALIDATOR_URL = url;
+	}
+
+	/**
+	 * Is the validation server accessible?
+	 * @throws SAREFPipelineException
+	 */
+	public static void PingValidationServer() throws SAREFPipelineException {
+		try {
+			URL url = new URL(VALIDATOR_URL);
+			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+			connection.setRequestMethod("GET");
+			connection.connect();
+			connection.getResponseCode();
+		} catch (IOException e) {
+			throw new SAREFPipelineException("response", "Unknown host: " + VALIDATOR_URL);
+		}
+		//logError(getMessage(ShaclValidationManager.MESSAGE.http_exception, VALIDATOR_URL));
+	}
+
+	/**
+	 * Preferred validation format is BASE64. Read file; return single BASE64-encoded string.
+	 * @throws SAREFPipelineException
+	 */
+	public static String FormatAsBase64(String ontologyFile) throws SAREFPipelineException {
+		try {
+			String value = Files.readString(Path.of(ontologyFile));  // 2Gb file size limit.
+			return Base64.getUrlEncoder().encodeToString(value.getBytes());
+		} catch (IOException ex) {
+			throw new SAREFPipelineException("FormatAsBase64", "Unable to format file as base64: " + ontologyFile);
+		}
 	}
 
-	public static HttpRequest.BodyPublisher ofForm(Map<String, String> data) {
+	public static HttpRequest.BodyPublisher ofForm(Map<String, Object> data) {
 		StringBuilder body = new StringBuilder();
-		for (String dataKey : data.keySet()) {
+		for (Object dataKey : data.keySet()) {
 			if (body.length() > 0) {
 				body.append("&");
 			}
-			body.append(encode(dataKey))
+			body.append(encodeBody(dataKey))
 					.append("=")
-					.append(encode(data.get(dataKey)));
+					.append(encodeBody(data.get(dataKey)));
 		}
 		return HttpRequest.BodyPublishers.ofString(body.toString());
 	}
 
 	/**
-	 * POST request to Validate a single RDF instance: {domain}/api/validate/{requestBody}
-	 <<< This method uses the validator configured to read the Clause_9_4_3_1_3.ttl, Clause_9_4_4_2.ttl, Clause_9_6_3.ttl shacl files.
-	 * Response: HTTP code 200 for successful validation. POST JSON return report format:
+	 * POST JSON response format:
 	 {
 	 "date": "2024-04-05T10:18:24.197+0000",
 	 "result": "SUCCESS",
@@ -121,57 +136,40 @@ public class ShaclValidationManager {
 	 "reports": {},
 	 "name": "SHACL Validation"
 	 }
-	 */
-	public HttpResponse<String> validateOntologyWithShacl(String shaclFile)
-			throws IOException, InterruptedException {
-		Map<String, String> data = new HashMap<>();
-		data = objectMapper.readValue(shaclRequestBody, HashMap.class);
-		data.put("contentToValidate", ontologyToValidate);
-		//data.put("validationType", validationType);
-		System.out.println("Map is: "+data);//<<<
-				/* "contentToValidate": "RDF_CONTENT_AS_BASE64_ENCODED_STRING",
-				"contentSyntax": "text/turtle",
-				"embeddingMethod": "BASE64",
-				"validationType": "Clause_9_4_3_1",
-				"reportSyntax": "application/json",
-				"locale": "en" */
-
-		HttpRequest request = HttpRequest.newBuilder()
-				.header("Content-Type", "text/turtle")	// application/x-www-form-urlencoded
-				.uri(URI.create(BASE_URL + "/api/validate" ))
-				.POST(ofForm(data))
-				.build();
-
-		HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
-		System.out.println("Status code: " + response.statusCode());
-		System.out.println("\n Body: " + response.body());
 
-		return response;
-	}
-
-	/**
-	 * If shaclDomain is empty, return info for all defined domains. http://localhost:8080/shacl/api/info
-	 * Not needed since a configured validator is not used -- the Clause_9_*.ttl files are augmented (parameterized) so they are only partially useful.
+	 * Generic validator option: 1. Replace {contentToValidate} value with the ontology to validate encoded in BASE64. (This can aos be done with URLs.)
+	 * 2. Configure the user-provided SHACL shape as a RuleSet element of the externalRules array. The content of each RuleSet is as follows:
+	 * [ "ruleSet": "BASE64-encoded_SHACL_shape", "embeddingMethod":"BASE64", "ruleSyntax": "text/turtle" ]   We run one SHACL shape at a time.
+	 * POST request to Validate a single RDF instance.
 	 * @throws IOException
 	 * @throws InterruptedException
 	 */
-	public HttpResponse<String> getShaclDomainInfo() throws IOException, InterruptedException {
-		Map<String, String> data = new HashMap<>();
-		data = objectMapper.readValue(shaclRequestBody, HashMap.class);
-
-		String url = BASE_URL + "shacl/api/info";
-
-		HttpRequest request = HttpRequest.newBuilder()
-				.header("Accept", "text/turtle")
-				.header("Content-Type", "text/turtle")
-				.uri(URI.create(url))
-				.GET()
-				.build();
-
-		HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
-		System.out.println("Status code: " + response.statusCode());
-		System.out.println("\n Body: " + response.body());
-
-		return response;
+	public HttpResponse<String> validateOntologyWithShacl(String shaclFile) throws SAREFPipelineException, InterruptedException {
+		try {
+			String ontologyBase64String = FormatAsBase64(this.ontologyToValidate);
+			String shaclBase64String = FormatAsBase64(shaclFile);
+			// populate shaclRequestBody json struct to map (no TypeReference)
+			String shaclRequestBody = "{ \"contentToValidate\": \"" + ontologyBase64String +
+				"\", \"embeddingMethod\": \"BASE64\", \"contentSyntax\": \"text/turtle\", \"reportSyntax\": \"application/json\", \"locale\": \"en\", \"rdfReportSyntax\": \"application/json\", \"externalRules\": [ { \"ruleSet\": \"" +
+					shaclBase64String + "\", \"embeddingMethod\": \"BASE64\", \"ruleSyntax\": \"text/turtle\" } ] }";
+			byte[] mapData = shaclRequestBody.getBytes();
+			Map<String,Object> myMap = objectMapper.readValue(mapData, HashMap.class);
+			// now update JSON data
+			//myMap.put("contentToValidate", ontologyBase64String);
+			//myMap.put("ruleSet", shaclBase64String);
+			HttpRequest request = HttpRequest.newBuilder()
+					.header("Content-Type", "text/turtle")    // application/x-www-form-urlencoded
+					.uri(URI.create(VALIDATOR_URL + "any/upload"))
+					.POST(ofForm(myMap))
+					.build();
+
+			HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
+			System.out.println("Status code: " + response.statusCode()); //<<<
+			System.out.println("\n Body: " + response.body());
+			return response;
+		} catch (IOException ex) {
+			throw new SAREFPipelineException("validateOntologyWithShacl", "Unable to process SHACL file: " + shaclFile);
+		}
 	}
+
 }
diff --git a/src/main/resources/messages/ShaclValidationManager.properties b/src/main/resources/messages/ShaclValidationManager.properties
index 9ac8047bb515f6eb91fa0dc4bb8a91e40bd85ce2..aab8431bd940767b46e93f7a7ba1a586b1e89d34 100644
--- a/src/main/resources/messages/ShaclValidationManager.properties
+++ b/src/main/resources/messages/ShaclValidationManager.properties
@@ -1,3 +1,3 @@
-http_exception=Error while making an HTTP request.
-ioexception=Error while accessing the local file system.
+http_exception=Error while making an HTTP request to `%s`
+ioexception=Error while accessing the local file system