diff --git a/EICAR/eicar b/EICAR/eicar
new file mode 100644
index 0000000000000000000000000000000000000000..704cac859b4ce00807c504f005c26a76542b6201
--- /dev/null
+++ b/EICAR/eicar
@@ -0,0 +1 @@
+X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..d458dba7b3a0de5643840768e2ce0e12819360f0
--- /dev/null
+++ b/META-INF/MANIFEST.MF
@@ -0,0 +1 @@
+Main-Class: org.slub.rosetta.dps.repository.plugin.SLUBVirusCheckClamAVPlugin
diff --git a/README.1st b/README.1st
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..392ce2dbcddb2aed13e36e2ba2192358b6a4ca76 100644
--- a/README.1st
+++ b/README.1st
@@ -0,0 +1,17 @@
+= EICAR =
+in directory EICAR/ is a file called "eicar", which contains the standard
+antivirus testsignature. This means that this file will ever ever trigger a
+virus alert in all known antivirus programs. This inot a bug, but a feature to
+ensure that "virus" files will be detected.
+
+Please test the plugin with this file:
+$> java -cp $EXLIBRISCLASSPATH:SLUBVirusCheckPlugin.jar org.slub.rosetta.dps.repository.plugin.SLUBVirusCheckClamAVPlugin EICAR/eicar 
+
+
+= Administer clamd =
+* Ensure clamd.conf enables tcp-sockets, the java prog could only use
+tcpsockets. Default is port 3310. The entry should look like: "TCPSocket 3310"
+
+= Compile =
+* make clean
+* make
diff --git a/java/org/slub/rosetta/dps/repository/plugin/SLUBVirusCheckClamAVPlugin.java b/java/org/slub/rosetta/dps/repository/plugin/SLUBVirusCheckClamAVPlugin.java
index 5ada144c32fe6e907bbd1fb86a3f98c54cbf8132..1a2252a51181e0300e4492731c61ba0c9d5ece44 100644
--- a/java/org/slub/rosetta/dps/repository/plugin/SLUBVirusCheckClamAVPlugin.java
+++ b/java/org/slub/rosetta/dps/repository/plugin/SLUBVirusCheckClamAVPlugin.java
@@ -1,13 +1,23 @@
 package org.slub.rosetta.dps.repository.plugin;
 
+
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.FileInputStream;
 import java.io.InputStream;
 import java.util.Calendar;
 import java.util.Date;
 import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.Iterator;
+import java.io.ByteArrayInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+
 
 import com.exlibris.core.infra.common.exceptions.logging.ExLogger;
 // import com.exlibris.dps.repository.plugin.virusCheck;
@@ -27,21 +37,128 @@ import com.exlibris.dps.repository.plugin.virusChcek.VirusCheckPlugin;
  * @see 
  */
 public class SLUBVirusCheckClamAVPlugin implements VirusCheckPlugin {
-	// constructor
-	SLUBVirusCheckClamAVPlugin () {
-	}
-	// scans a given file for viruses
-	public void scan(String fileFullPath) {
-	}
-	// outcome of virus check
-	public String getOutput () {
-		return null; // dummy
-	}
-	public String getAgent () {
-		return null; // dummy
-	}
-	public boolean isVirusFree() {
-		return true; // dummy
+  //private static final ExLogger log = ExLogger.getExLogger(SLUBVirusCheckClamAVPlugin.class);
+  private static final int DEFAULT_CHUNK_SIZE = 2048;
+  private static final byte[] INSTREAM = "zINSTREAM\0".getBytes();
+  private static final String RESPONSEOK = "stream: OK";
+  private static final String FOUND_SUFFIX = "FOUND";
+  private static final String STREAM_PREFIX = "stream: ";
+  private enum Status { PASSED, FAILED };
+  
+  private int timeout;
+  private String host;
+  private int port;
+  private String response;
+  private Status status = Status.FAILED;
+  private String signature = "";
+
+  // constructor
+  SLUBVirusCheckClamAVPlugin (String host, int port, int timeout) {
+    this.host = host;
+    this.port = port;
+    this.timeout = timeout;
+    //log.info("SLUBVirusCheckPlugin instantiated with host=" + host + " port=" + port + " timeout=" + timeout);
+    System.out.println( "SLUBVirusCheckPlugin instantiated with host=" + host + " port=" + port + " timeout=" + timeout);
+  }
+  
+  // getter, ex.: get Host, port, timeout
+  protected String getHost() { return this.host; }
+  protected int getPort() { return this.port; }
+  protected int getTimeOut() { return this.timeout; }
+  protected String getSignature() { return this.signature; }
+  protected Status getStatus() { return status; }
+  
+  // setter  
+  protected void setSignature(String signature) {
+    this.signature = signature;
+  }
+  protected void setStatus(Status status) {
+    this.status = status;
+  }
+  
+  // scans a given file for viruses
+  public void scan(String fileFullPath) {
+  	try {
+    // create a socket
+    Socket socket = new Socket ();
+    //socket.connect( new InetSocketAddress(getHost()));
+    socket.connect( new InetSocketAddress(getHost(), getPort()));
+    try {
+      socket.setSoTimeout( getTimeOut() );
+    } catch (SocketException e) {
+    	System.out.println( "Could not set socket timeout to " + getTimeOut() + "ms " + e);
+      //log.error( "Could not set socket timeout to " + getTimeOut() + "ms", e);
+    }
+    InputStream in = new FileInputStream( fileFullPath ); 
+    // send stream
+    DataOutputStream dos = null;
+    response = "";
+    try {
+      dos = new DataOutputStream(socket.getOutputStream());
+      dos.write(INSTREAM);
+      int read;
+      byte[] buffer = new byte[DEFAULT_CHUNK_SIZE];
+      while ((read = in.read(buffer))> 0) {
+        dos.writeInt(read);
+        dos.write(buffer, 0, read);
+      }
+      dos.writeInt(0);
+      dos.flush();
+      read = socket.getInputStream().read(buffer);
+      if (read > 0) response = new String(buffer, 0, read);
+    } finally {
+      if (dos != null) try { dos.close(); } catch (IOException e) { 
+        // log.debug("exception closing DOS", e);
+        System.out.println( "exception closing DOS "+ e );
+      }
+      try { socket.close(); } catch (IOException e) { 
+        // log.debug("exception closing socket", e); 
+        System.out.println( "exception closing socket "+ e);
+      }
+    }
+    //log.debug( "Response: " + response);
+    System.out.println("Response: " + response);
+    // parse return code
+    String result = response.trim();
+    if (RESPONSEOK.equals( result ) ) {
+      setStatus(Status.PASSED);
+    } else if ( result.endsWith(FOUND_SUFFIX) ) {
+      setStatus(Status.FAILED);
+      setSignature(result.substring(STREAM_PREFIX.length(), result.lastIndexOf(FOUND_SUFFIX) - 1 ));
+    } else {
+      setStatus(Status.FAILED);
+      //log.warn("clamd protocol not fully implemented");
+      System.out.println("clamd protocol not fully implemented");
+    }
+    } catch (IOException e) {
+    	//log.error("exception creation socket, clamd not available at host=" + host + "port=" + port, e);
+    	System.out.println ("exception creation socket, clamd not available at host=" + host + "port=" + port + " " + e);
+    	setStatus(Status.FAILED);
+    	setSignature("ERROR: clamd not available");
+    }
+  }
+  
+  // outcome of virus check
+  public String getOutput () {
+    return getSignature();
+  }
+  
+  public String getAgent () {
+    return "clamd";
+  }
+  
+  public boolean isVirusFree() {
+    //return true; // dummy
+    return (Status.PASSED  == getStatus());
+  }
+  
+  // stand alone check
+  public static void main(String [] args) {
+  	SLUBVirusCheckClamAVPlugin plugin = new SLUBVirusCheckClamAVPlugin( "127.0.0.1", 3310, 60);
+  	for (String file:args) {
+  		plugin.scan( file );
+  		System.out.println("RESULT: " + plugin.isVirusFree() + " SIGNATURE: " + plugin.getOutput());
+  	}
 	}
 }