diff --git a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java
index 61b2800..f16bed2 100644
--- a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java
+++ b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java
@@ -1,5 +1,8 @@
 package de.ids_mannheim.korap.plkexport;
 
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.lang.Thread;
@@ -53,6 +56,25 @@
 import freemarker.template.Configuration;
 import freemarker.template.Template;
 
+/**
+ * TODO
+ * This is only a draft!!!
+ * Has to be integrated in Nils sourcecode
+ * 
+ * Export works only for rtf, JSON has to be integrated
+ * 
+ * Delete the temp file of the export at the end
+ * 
+ * Get variable cutoff from URL
+ * 
+ * Right now, the web service returns one page (cutoff=1) or all
+ * pages.
+ * There is now limitations of hits. ("Beschränken auf xy Treffer")
+ * does not work right now.
+ * 
+ * ------------------------------------------------------------
+ * Works with the export demo
+ */
 
 @Path("/")
 public class IdsExportService {
@@ -127,7 +149,14 @@
                     .build());
         }
 
-        ResponseBuilder builder;
+
+        int totalhits;
+
+        //TODO cutoff to try out, retrieve it  later:
+        boolean cutoff = false;
+        //boolean cutoff = true;
+
+        ResponseBuilder builder = null;
         Client client = ClientBuilder.newClient();
 
         String scheme = properties.getProperty("api.scheme", "https");
@@ -158,7 +187,7 @@
             uri = uri.queryParam("count", ExWSConf.MAX_EXP_LIMIT);
         };
         */
-        uri = uri.queryParam("count", 50);
+        uri = uri.queryParam("count", ExWSConf.PAGE_SIZE);
 
         // Get client IP, in case service is behind a proxy
         String xff = "";
@@ -207,8 +236,9 @@
         };
     
         String resp;
+        WebTarget resource;
         try {
-            WebTarget resource = client.target(uri.build());
+            resource = client.target(uri.build());
             Invocation.Builder reqBuilder = resource.request(MediaType.APPLICATION_JSON);
             if (xff != "") {
                 reqBuilder = reqBuilder.header("X-Forwarded-For", xff);
@@ -227,35 +257,82 @@
             fname = q;
         }
 
-        //format == json
+        // format == json
         if (format.equals("json")) {
             builder = Response.ok(resp);
             builder.type(MediaType.APPLICATION_JSON);
         }
 
-        // format == rtf / else
+        // format == rtf
         else {
             ObjectMapper mapper = new ObjectMapper();
             JsonFactory factory = mapper.getFactory();
             JsonParser parser = factory.createParser(resp);
             JsonNode actualObj = mapper.readTree(parser);
-            JsonNode jsonNode1 = actualObj.get("matches");
-            LinkedList<MatchExport> listMatches = new LinkedList();
-            ObjectMapper objectMapper = new ObjectMapper();
-            MatchExport match;
 
-            for (Iterator<JsonNode> itNode = jsonNode1.elements(); itNode
-                    .hasNext();) {
-                match = objectMapper.readValue(itNode.next().toString(),
-                        MatchExport.class);
-                listMatches.addLast(match);
+            /*
+             * Get total results
+             */
+            totalhits = actualObj.at("/meta").get("totalResults").asInt();
+
+            // If only one page should be exported there is no need for an temporary export file
+            if (cutoff) {
+                String rtfresp = getRtf(resp);
+                builder = Response.ok(rtfresp);
             }
 
-            String rtfresp = writeRTF(listMatches);
-            builder = Response.ok(rtfresp);
+            if (!cutoff) {
+           
+                /*
+                 *  Get number of pages and the number of hits 
+                 *  which should be exported at the last page
+                 */
+                int pg = 1;
+                int dr = totalhits % ExWSConf.PAGE_SIZE;
+                if (dr > 0) {
+                    pg = totalhits / ExWSConf.PAGE_SIZE + 1;
+                }
+                else {
+                    pg = totalhits / ExWSConf.PAGE_SIZE;
+                }
+
+                /*
+                 * Create temporary file
+                 */
+                File expTmp = createTempFile("idsexppl-", format);
+                FileWriter fw = new FileWriter(expTmp, true);
+                BufferedWriter bw = new BufferedWriter(fw);
+                //better delete after it is not needed anymore
+                expTmp.deleteOnExit();
+            
+                // position of pages, 1 = first page, 2 = middle pages, 3 = last page
+                int pos = 0;
+                // String urlorg = url;
+                uri.queryParam("page", "{PAGE}");
+                for (int i = 1; i <= pg; i++) {
+                    // url = urlorg + "&page=" + i;
+                    // resource = client.target(url);
+                    resource = client.target(uri.build(i));
+                    resp = resource.request(MediaType.APPLICATION_JSON)
+                        .get(String.class);
+
+                    if (i < pg) {
+                        pos = 2;
+                    }
+                    if (i == 1) {
+                        pos = 1;
+                    }
+                    if (pg == i) {
+                        pos = 3;
+                    }
+                    getRtf(expTmp, fw, resp, bw, pos, dr);
+                }
+                builder = Response.ok(expTmp);
+            }
+
             builder.type("application/rtf");
             format = "rtf";
-        }
+        };        
 
         builder.header(
             "Content-Disposition",
@@ -332,7 +409,7 @@
         };
 
         return resp.build();
-    }
+    };
 
     
     @GET
@@ -342,9 +419,54 @@
         return Response
             .ok(exportJsStr, "application/javascript")
             .build();
-    };    
+    };
 
-    public String writeRTF (LinkedList list) {
+
+    /*
+     * returns export results of one page as rtf String 
+     */
+    public String getRtf (String resp) throws IOException {
+        LinkedList<MatchExport> listMatches = getListMatches(resp);
+        return writeRTF(listMatches);
+    };
+
+
+    /* 
+     * Writes result of export pages to temporary file
+     */
+    public void getRtf (File file, FileWriter filewriter, String resp,
+            BufferedWriter bw, int pos, int dr) throws IOException {
+        LinkedList<MatchExport> listMatches = getListMatches(resp);
+        writeRTF(listMatches, file, filewriter, bw, pos, dr);
+    };
+    
+    
+    /*
+     * returns LinkedList of Matches
+     */
+    public LinkedList<MatchExport> getListMatches (String resp)
+            throws IOException {
+        ObjectMapper mapper = new ObjectMapper();
+        JsonFactory factory = mapper.getFactory();
+        JsonParser parser = factory.createParser(resp);
+        JsonNode actualObj = mapper.readTree(parser);
+        JsonNode jsonNode1 = actualObj.get("matches");
+        LinkedList<MatchExport> listMatches = new LinkedList();
+        ObjectMapper objectMapper = new ObjectMapper();
+        MatchExport match;
+
+        for (Iterator<JsonNode> itNode = jsonNode1.elements(); itNode
+                .hasNext();) {
+            match = objectMapper.readValue(itNode.next().toString(),
+                    MatchExport.class);
+            listMatches.addLast(match);
+        };
+        return listMatches;
+    };
+    
+  
+
+    public String getRtfSection (LinkedList list, int pos, int dr) {
         LinkedList matchlist = list;
         RtfTextPara par = p((" "));
         RtfTextPara[] pararray;
@@ -354,14 +476,18 @@
         String reference;
         String textSigle;
         int j = matchlist.size();
-
+        if (dr != 0 && pos == 3) {
+            j = dr;
+        }
+        
         //TODO Add export plugin version to JSON output?
-        /*
-         * TODO 
-         * The output rtf file lacks style, 
-         * but I'm thinking about changing the jRTF library to OpenRTF https://github.com/LibrePDF/OpenRTF, 
-         * because jRTF is very rudimentary, so I only list the information in a section right now.
-         */
+        //
+         // TODO 
+         // The output rtf file lacks style, 
+         // but I'm thinking about changing the jRTF library to OpenRTF https://github.com/LibrePDF/OpenRTF, 
+         // because jRTF is very rudimentary, so I only list the information in a section right now.
+         //
+
         RtfTextPara pv = getVersion();
         listp.add(pv);
 
@@ -378,11 +504,61 @@
             listp.add(par);
         }
 
+
         String rtfresp = rtf().section(listp).toString();
         return rtfresp;
+
     }
 
+    
+    public String writeRTF (LinkedList list) throws IOException {
+        String rtfresp =  getRtfSection(list, 0, 0);
+        return rtfresp;
+    }
+    
+    public void writeRTF (LinkedList list, File file, FileWriter filewriter,
+            BufferedWriter bw, int pos, int dr) throws IOException {
+   
+        String rtfresp = getRtfSection(list, pos,dr);
+        
+        switch (pos) {
 
+            case 1: {
+                rtfresp = rtfresp.substring(0, rtfresp.length() - 1);
+                bw.append(rtfresp);
+                bw.flush();
+                break;
+            }
+
+            case 2: {
+                rtfresp = rtfresp.substring(143, rtfresp.length() - 1);
+                bw.append(rtfresp);
+                bw.flush();
+                break;
+            }
+
+            case 3: {
+                rtfresp = rtfresp.substring(143);
+                bw.append(rtfresp);
+                bw.flush();
+                bw.close();
+                break;
+            }
+
+            default: {
+                //TODO Error Handling
+                System.out.println("Invalid pos Parameter");
+                break;
+            }
+        }
+
+        return;
+
+    }
+
+    /**
+     *  Get version for RTF document 
+     *  */
     public RtfTextPara getVersion () {
         Version version = new Version(ExWSConf.VERSION_MAJOR,
                 ExWSConf.VERSION_MINOR, ExWSConf.VERSION_PATCHLEVEL, null, null,
@@ -412,4 +588,20 @@
 
         return "";
     }
+
+    /**
+     * Creates file to hold the result temporarily
+     *
+     */
+    public static File createTempFile (String name, String suffix) {
+        try {
+            File temp = File.createTempFile(name, "." + suffix);
+            return temp;
+
+        }
+        catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
 }
