diff --git a/data-access/servlet/src/main/java/cutout/webapi/ServletCutout.java b/data-access/servlet/src/main/java/cutout/webapi/ServletCutout.java
index f474100300864de6cffcce7e4e08d48c99463d57..2c46e7d4c7293420a12358eeab232eb4b118ce6b 100644
--- a/data-access/servlet/src/main/java/cutout/webapi/ServletCutout.java
+++ b/data-access/servlet/src/main/java/cutout/webapi/ServletCutout.java
@@ -4,6 +4,8 @@ import java.util.logging.Level;
 
 import java.security.Principal;
 
+import java.time.Instant;
+
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
@@ -159,8 +161,11 @@ public class ServletCutout extends HttpServlet
             LOGGER.fine("Resolver returns subsurveyId null: no extraCards loaded.");
          }
 
+         String cutAbsPathname = settings.fitsPaths.cutouts() + "/"
+                          + generateSubimgPathname(resolver.relPathname(), resolver.hdunum());
+
          return vlkb.doFile(resolver.relPathname(), resolver.hdunum(),
-               pos, band, time, pol, pixels, countNullValues, extraCards);
+               pos, band, time, pol, pixels, countNullValues, extraCards, cutAbsPathname);
       }
 
 
@@ -337,6 +342,26 @@ public class ServletCutout extends HttpServlet
    }
 
 
+   private  String generateSubimgPathname(String relPathname, int hdunum)
+   {
+      String cutfitsname = "vlkb-cutout";
+
+      Instant instant = Instant.now() ;
+      String timestamp = instant.toString().replace(":","-").replace(".","_");
+
+      String tempPathname1 = relPathname.replaceAll("/","-");
+      String tempPathname2 = tempPathname1.replaceAll(" ","_");
+
+      if(hdunum == 1)
+      {
+         return cutfitsname + "_" + timestamp + "_" + tempPathname2;
+      }
+      else
+      {
+         String extnum = "EXT" + String.valueOf(hdunum-1);
+         return cutfitsname + "_" + timestamp + "_" + extnum + "_" + tempPathname2;
+      }
+   }
 
 
 
diff --git a/data-access/servlet/src/main/java/mcutout/VlkbCli.java b/data-access/servlet/src/main/java/mcutout/VlkbCli.java
index fc010cfb9df51470b152cae3c8b13da101ce15ea..64835336eb53d466808d75bbf140b382f405766d 100644
--- a/data-access/servlet/src/main/java/mcutout/VlkbCli.java
+++ b/data-access/servlet/src/main/java/mcutout/VlkbCli.java
@@ -5,8 +5,6 @@ import java.util.List;
 import java.util.ArrayList;
 import java.util.Arrays;
 
-import java.time.Instant;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -22,6 +20,7 @@ import java.nio.file.StandardOpenOption;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import org.apache.commons.io.FilenameUtils;
 
 import java.time.*;// Timestamp in cut-filename
 import java.io.ByteArrayOutputStream; // for SODA direct streaming doSubimgStream
@@ -80,7 +79,6 @@ class VlkbCli implements Vlkb
    }
 
 
-
    public CutResult doMerge(String[] idArr, Coord coord, boolean countNullValues)
       throws FileNotFoundException, IOException
    {
@@ -90,335 +88,323 @@ class VlkbCli implements Vlkb
    }
 
 
-
    public CutResult doFile(String relPathname, int hdunum,
          Pos pos, Band band, Time time, Pol pol, String pixels,
-         boolean countNullValues, FitsCard[] extraCards)
+         boolean countNullValues, FitsCard[] extraCards,
+			String cutAbsPathname)
          throws IOException, InterruptedException
       {
          LOGGER.fine("trace: " + pos.toString() );
+         LOGGER.finer("Using doStream() to local file : " + cutAbsPathname);
 
-         CutResult cutResult = new CutResult();
-
-         LOGGER.finer("Using doStream() to local file");
-
-         String absSubimgPathname = settings.fitsPaths.cutouts()
-            + "/" + generateSubimgPathname(relPathname, hdunum);
-
-         LOGGER.finer("Uses local filename : " + absSubimgPathname);
-
-         OutputStream fileOutputStream = new FileOutputStream( new File(absSubimgPathname) );
-
-         soda.doStream(relPathname, hdunum, pos, band, time, pol, pixels, fileOutputStream);
-
-         // engine returns absPathname see common/cutout.cpp::do_cutout_file()
-         cutResult.fileName = absSubimgPathname;
-         cutResult.fileSize = Files.size(Paths.get(absSubimgPathname));
-
-         if(countNullValues)
-         {
-            cutResult.nullValueCount = doCountNullValues(absSubimgPathname, 1);
-         }
-
-         if(extraCards == null || (extraCards.length < 1))
-         {
-            LOGGER.finer("Adding extraCards to cut-file implemented only in VlkbAmql");
-         }
-
-         cutResult.pixels = null;
-         return cutResult;
-      }
-
-
-
-   private NullValueCount doCountNullValues(String absPathname, int hdunum)
-         throws IOException, InterruptedException
-      {
-         ByteArrayOutputStream bos = new ByteArrayOutputStream();
-         if(bos == null)
-            throw new AssertionError("byte output stream for bounds was not created, is null");
-
-         String[] cmdBounds = new String[3];
-         cmdBounds[0] = "/usr/local/bin/vlkb";
-         cmdBounds[1] = "nullvals";
-         cmdBounds[2] = absPathname;
-
-         ExecCmd exec = new ExecCmd();
-         exec.doRun(bos, cmdBounds);
-         LOGGER.finest("exec NullVals exitValue: " + exec.exitValue);
-
-         bos.close();
-
-         boolean hasResult = (exec.exitValue == 0);
-         if(hasResult)
-         {
-            String nullValsString = new String(bos.toByteArray());
-            LOGGER.finest("vlkb nullvals: " + nullValsString);
-
-            if((nullValsString != null) && nullValsString.trim().isEmpty())
-            {
-               throw new AssertionError("'vlkb nullvals' returned empty string");
-            }
-
-            // parse result: '<fill-ratio> <nullvals-count> <tot-count>'
-
-            String[] splitStr = nullValsString.trim().split("\\s+");
-            if(splitStr.length != 3)
-               throw new AssertionError("'vlkb nullvals' did not return 3 numbers but: " + nullValsString);
-
-            NullValueCount nvc = new NullValueCount();
-            nvc.percent = Double.parseDouble(splitStr[0]);
-            nvc.nullCount = Long.parseLong(splitStr[1]);
-            nvc.totalCount = Long.parseLong(splitStr[2]);
-            return nvc;
-         }
-         else
-         {
-            throw new AssertionError("'vlkb nullvals' exited without results for: " + absPathname);
-         }
-      }
-
-
-
-
-   private CutResult doFileById(String id, Pos pos, Band band, Time time, Pol pol, String pixels,
-         boolean countNullValues/*, Subsurvey[] subsurveys*/)
-         throws IOException, InterruptedException
-      {
-         LOGGER.fine("trace");
-
-         FitsCard[] extraCards = null;
-
-         this.resolver.resolve(id);
-         String relPathname = this.resolver.relPathname();
-         int hdunum         = this.resolver.hdunum();
-         String subsurveyId = this.resolver.obsCollection();
-
-         if(subsurveyId != null)
-         {
-            extraCards = Subsurvey.subsurveysFindCards(this.subsurveys, subsurveyId);
-         }
-         else
-         {
-            LOGGER.finer("Resolver returns subsurveyId null: no extraCards loaded.");
-         }
-
-         final String DEFAULT_TIME_SYSTEM = "MJD_UTC"; // FIXME take from confif file
-
-         CutResult cutResult = doFile(relPathname, hdunum, pos, band, time, pol, pixels,
-               countNullValues, extraCards);
-
-         return cutResult;
-      }
-
-
-   private  String generateSubimgPathname(String relPathname, int hdunum)
-   {
-      String cutfitsname = "vlkb-cutout";
-
-      Instant instant = Instant.now() ;
-      String timestamp = instant.toString().replace(":","-").replace(".","_");
-
-      String tempPathname1 = relPathname.replaceAll("/","-");
-      String tempPathname2 = tempPathname1.replaceAll(" ","_");
-
-      if(hdunum == 1)
-      {
-         return cutfitsname + "_" + timestamp + "_" + tempPathname2;
-      }
-      else
-      {
-         String extnum = "EXT" + String.valueOf(hdunum-1);
-         return cutfitsname + "_" + timestamp + "_" + extnum + "_" + tempPathname2;
-      }
-   }
-
-
-
-
-   public MCutResult doMCutout(String jdlJson)
-         throws IOException, InterruptedException
-      {
-         LOGGER.fine("trace");
-
-         MCutResult mCutResult;
-
-         CutArgs[] cutArgsArr = CutArgs.parseCutArgsArr(jdlJson);
-         MCutResult.Cut[] cutResultArr = doCutouts( cutArgsArr );
-         String respJsonString = genResponseJson( cutResultArr );
-         mCutResult = doCompressCutFiles( cutResultArr, respJsonString );
-
-         return mCutResult;
-      }
-
-
-
-   private MCutResult.Cut[] doCutouts(CutArgs[] cutArgsArr)
-   {
-      LOGGER.fine("trace, count of cuts : " + String.valueOf( cutArgsArr.length ) );
-
-      List<MCutResult.Cut> cutResList = new ArrayList<MCutResult.Cut>();
-
-      int ix = 0;
-      for(CutArgs cutArgs: cutArgsArr)
-      {
-         MCutResult.Cut cut = doFileByIdWithErr(cutArgs.id,
-               cutArgs.pos, cutArgs.band, cutArgs.time,  cutArgs.pol,  cutArgs.pixels,
-               cutArgs.countNullValues);//,  null);//cutArgs.extraCards);
-
-         cut.index = ix++;
-
-         LOGGER.finest("cut" + String.valueOf(cut.index) + " : " + cut.content);
-
-         cutResList.add(cut);
-      }
-
-      return cutResList.toArray(new MCutResult.Cut[0]);
-   }
-
-
-   // FIXME implement similar for Merge: MCutResult = call-Montage-demosaic-sequence(cutResultArr)
-   private MCutResult doCompressCutFiles(MCutResult.Cut[] cutArr, String respJsonString)
-         throws IOException, InterruptedException
-      {
-         Instant instant = Instant.now();
-         String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + "_" + instant.getNano();
-
-         final String tgzFileName = settings.fitsPaths.cutouts() + "/mcutout_" + timestamp + ".tar.gz";
-
-         // generate response-*.json with timestamp
-         String respJsonPathname = settings.fitsPaths.cutouts() + "/response_" + timestamp + ".json";
-         try (PrintWriter out = new PrintWriter(respJsonPathname))
-         {
-            out.print(respJsonString);
-         }
-
-         List<Path> paths = new ArrayList<Path>();
-
-         paths.add(Paths.get(respJsonPathname));
+			try(OutputStream fileOutputStream = new FileOutputStream(new File(cutAbsPathname)))
+			{
+				soda.doStream(relPathname, hdunum, pos, band, time, pol, pixels,fileOutputStream);
+			}
 
-         for(MCutResult.Cut cut : cutArr)
-         {
-            LOGGER.finest("cut-id"+ String.valueOf(cut.index) + " -> " + cut.content);
-            if(cut.contentType == MCutResult.Cut.ContentType.FILENAME)
-            {
-               Path p = Paths.get(cut.content);
-               paths.add(p);
-            }
-         }
+			CutResult cutResult = new CutResult();
 
-         Path output = Paths.get(tgzFileName);
-         createTarGzipFiles(paths, output);
+			cutResult.fileName = cutAbsPathname;
+			cutResult.fileSize = Files.size(Paths.get(cutAbsPathname));
+			if(countNullValues)
+			{
+				cutResult.nullValueCount = doCountNullValues(cutAbsPathname, 1);
+			}
+			if(extraCards == null || (extraCards.length < 1))
+			{
+				LOGGER.finer("Adding extraCards to cut-file implemented only in VlkbAmql");
+			}
+			cutResult.pixels = null;
+
+			return cutResult;
+		}
+
+
+   public MCutResult doMCutout(String jdlJson, String workDir)
+		throws IOException, InterruptedException
+		{
+			LOGGER.fine("trace");
 
-         MCutResult mCutResult = new MCutResult();
-         mCutResult.cutResArr = cutArr;
-         mCutResult.fileName = tgzFileName;
-         mCutResult.resJsonPathname = respJsonPathname;
-         mCutResult.fileSize = Files.size(output);
+			MCutResult mCutResult;
+
+			CutArgs[] cutArgsArr = CutArgs.parseCutArgsArr(jdlJson);
+			MCutResult.Cut[] cutResultArr = doCutouts( cutArgsArr, workDir );
+			String respJsonString = genResponseJson( cutResultArr );
+			mCutResult = doCompressCutFiles( cutResultArr, respJsonString );
+
+			return mCutResult;
+		}
+
+
+
+	private MCutResult.Cut[] doCutouts(CutArgs[] cutArgsArr, String workDir)
+	{
+		LOGGER.fine("trace, count of cuts : " + String.valueOf( cutArgsArr.length ) );
+
+		List<MCutResult.Cut> cutResList = new ArrayList<MCutResult.Cut>();
+
+		int ix = 0;
+		for(CutArgs cutArgs: cutArgsArr)
+		{
+			MCutResult.Cut cut = doFileByIdWithErr(cutArgs.id,
+					cutArgs.pos, cutArgs.band, cutArgs.time,  cutArgs.pol,  cutArgs.pixels,
+					cutArgs.countNullValues, workDir, ix);//, null);//cutArgs.extraCards);
+
+			cut.index = ix++;
+
+			LOGGER.finest("cut" + String.valueOf(cut.index) + " : " + cut.content);
+
+			cutResList.add(cut);
+		}
+
+		return cutResList.toArray(new MCutResult.Cut[0]);
+	}
+
+
+	private MCutResult.Cut doFileByIdWithErr(String id, Pos pos, Band band, Time time, Pol pol,
+			String pixels, boolean countNullValues/*, Subsurvey[] subsurveys*/,
+			String workDir, int ix)
+	{
+		LOGGER.fine("trace");
+
+		MCutResult mCutResult = new MCutResult();
+		MCutResult.Cut cut = mCutResult.new Cut(/* FIXME eventually add here new Inputs(id, pos,..) */);
+
+		try
+		{
+			this.resolver.resolve(id);
+			String relPathname = this.resolver.relPathname();
+			int hdunum         = this.resolver.hdunum();
+			String subsurveyId = this.resolver.obsCollection();
+
+			FitsCard[] extraCards = null;
+
+			if(subsurveyId != null)
+			{
+				extraCards = Subsurvey.subsurveysFindCards(this.subsurveys, subsurveyId);
+			}
+			else
+			{
+				LOGGER.finer("Resolver returns subsurveyId null: no extraCards loaded.");
+			}
+
+			final String DEFAULT_TIME_SYSTEM = "MJD_UTC"; // FIXME take from config file
+
+			final int MAX_FILENAME_LEN = 100; // bytes, tar-entry max length is 100bytes
+			String cutAbsPathname = workDir + "/"
+				+ generateSubimgPathname(ix, relPathname, hdunum, MAX_FILENAME_LEN);
+
+			CutResult cutResult = doFile(relPathname, hdunum, pos, band, time, pol, pixels,
+					countNullValues, extraCards, cutAbsPathname);
+
+			cut.content     = cutResult.fileName;
+			cut.contentType = MCutResult.Cut.ContentType.FILENAME;
+		}
+		catch(MultiValuedParamNotSupported ex)
+		{
+			cut.content = "MultiValuedParamNotSupported: " + ex.getMessage();
+			cut.contentType = MCutResult.Cut.ContentType.BAD_REQUEST;
+			LOGGER.warning(cut.content);
+		}
+		catch(IllegalArgumentException ex)
+		{
+			cut.content = "IllegalArgumentException: " + ex.getMessage();
+			cut.contentType = MCutResult.Cut.ContentType.BAD_REQUEST;
+			LOGGER.warning(cut.content);
+		}
+		catch(Exception ex)
+		{
+			cut.content     = "Exception: " + ex.getMessage();
+			cut.contentType = MCutResult.Cut.ContentType.SERVICE_ERROR;
+			LOGGER.severe(cut.content);
+			ex.printStackTrace();
+		}
+
+		return cut;
+	}
+
+
+
+	// FIXME implement similar for Merge: MCutResult = call-Montage-demosaic-sequence(cutResultArr)
+	private MCutResult doCompressCutFiles(MCutResult.Cut[] cutArr, String respJsonString)
+		throws IOException, InterruptedException
+		{
+			Instant instant = Instant.now();
+			String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + "_" + instant.getNano();
+
+			final String tgzFileName = settings.fitsPaths.cutouts()
+				+ "/mcutout_" + timestamp + ".tar.gz";
+			// generate response-*.json with timestamp
+			String respJsonPathname = settings.fitsPaths.cutouts()
+				+ "/response_" + timestamp + ".json";
+
+			try (PrintWriter out = new PrintWriter(respJsonPathname))
+			{
+				out.print(respJsonString);
+			}
+
+			List<Path> paths = new ArrayList<Path>();
+
+			paths.add(Paths.get(respJsonPathname));
+
+			for(MCutResult.Cut cut : cutArr)
+			{
+				LOGGER.finest("cut-index"+ String.valueOf(cut.index) + " -> " + cut.content);
+				if(cut.contentType == MCutResult.Cut.ContentType.FILENAME)
+				{
+					Path p = Paths.get(cut.content);
+					paths.add(p);
+				}
+			}
+
+			Path output = Paths.get(tgzFileName);
+			createTarGzipFiles(paths, output);
+
+			MCutResult mCutResult = new MCutResult();
+			mCutResult.cutResArr = cutArr;
+			mCutResult.fileName = tgzFileName;
+			mCutResult.resJsonPathname = respJsonPathname;
+			mCutResult.fileSize = Files.size(output);
+
+			return mCutResult;
+		}
+
+
+	private String genResponseJson(MCutResult.Cut[] cutArr)
+	{
+		List<Path> paths = new ArrayList<Path>();
+
+		JSONArray jArr = new JSONArray();
+
+		for(MCutResult.Cut cut : cutArr)
+		{
+			jArr.add(cut.toJsonObject());
+		}
+
+		return jArr.toString();
+	}
+
+
+	/*
+		<dependency>
+		<groupId>org.apache.commons</groupId>
+		<artifactId>commons-compress</artifactId>
+		<version>1.20</version>
+		</dependency>
+
+		import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+		import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
+		import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+	 */
+	private static void createTarGzipFiles(List<Path> paths, Path output)
+		throws IOException
+		{
+			try (OutputStream fOut = Files.newOutputStream(output);
+					BufferedOutputStream buffOut = new BufferedOutputStream(fOut);
+					GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(buffOut);
+					TarArchiveOutputStream tOut = new TarArchiveOutputStream(gzOut))
+			{
+				for (Path path : paths)
+				{
+					if (!Files.isRegularFile(path))
+					{
+						throw new IOException("Must be regular file, but was : " + path.toString());
+					}
+
+					TarArchiveEntry tarEntry = new TarArchiveEntry(
+							path.toFile(),
+							path.getFileName().toString());
+
+					tOut.putArchiveEntry(tarEntry);
+					Files.copy(path, tOut); // NOTE tar limits max filename length <100bytes
+					tOut.closeArchiveEntry();
+				}
+
+				tOut.finish();
+			}
+		}
+
+
+	private NullValueCount doCountNullValues(String absPathname, int hdunum)
+		throws IOException, InterruptedException
+		{
+			ByteArrayOutputStream bos = new ByteArrayOutputStream();
+			if(bos == null)
+				throw new AssertionError("byte output stream for bounds was not created, is null");
+
+			String[] cmdBounds = new String[3];
+			cmdBounds[0] = "/usr/local/bin/vlkb";
+			cmdBounds[1] = "nullvals";
+			cmdBounds[2] = absPathname;
+
+			ExecCmd exec = new ExecCmd();
+			exec.doRun(bos, cmdBounds);
+			LOGGER.finest("exec NullVals exitValue: " + exec.exitValue);
+
+			bos.close();
+
+			boolean hasResult = (exec.exitValue == 0);
+			if(hasResult)
+			{
+				String nullValsString = new String(bos.toByteArray());
+				LOGGER.finest("vlkb nullvals: " + nullValsString);
+
+				if((nullValsString != null) && nullValsString.trim().isEmpty())
+				{
+					throw new AssertionError("'vlkb nullvals' returned empty string");
+				}
+
+				// parse result: '<fill-ratio> <nullvals-count> <tot-count>'
+
+				String[] splitStr = nullValsString.trim().split("\\s+");
+				if(splitStr.length != 3)
+					throw new AssertionError("'vlkb nullvals' did not return 3 numbers but: " + nullValsString);
+
+				NullValueCount nvc = new NullValueCount();
+				nvc.percent = Double.parseDouble(splitStr[0]);
+				nvc.nullCount = Long.parseLong(splitStr[1]);
+				nvc.totalCount = Long.parseLong(splitStr[2]);
+				return nvc;
+			}
+			else
+			{
+				throw new AssertionError("'vlkb nullvals' exited without results for: " + absPathname);
+			}
+		}
+
+
+
+	private  String generateSubimgPathname(int ix, String relPathname, int hdunum, int maxLen)
+	{
+		String cutfitsname = String.valueOf(ix);
+
+		String tempPathname1 = relPathname.replaceAll("/","-");
+		String tempPathname2 = tempPathname1.replaceAll(" ","_");
+		String filename;
+
+		if(hdunum == 1)
+		{
+			filename = cutfitsname + "_" + tempPathname2;
+		}
+		else
+		{
+			String extnum = "E" + String.valueOf(hdunum-1);
+			filename = cutfitsname + "_" + extnum + "_" + tempPathname2 ;
+		}
+
+		// shorten filename to maxLen
+
+		if(filename.length() > maxLen) // FIXME consider UTF-8 ? string-len != string-buff-len
+		{
+			String ext  = FilenameUtils.getExtension(filename);// without dot
+			String name = FilenameUtils.removeExtension(filename);
+
+			filename = name.substring(0, maxLen - 1 - ext.length() ) + "." + ext;
+		}
+
+		return filename;
+	}
 
-         return mCutResult;
-      }
-
-
-   private String genResponseJson(MCutResult.Cut[] cutArr)
-   {
-      List<Path> paths = new ArrayList<Path>();
-
-      JSONArray jArr = new JSONArray();
-
-      for(MCutResult.Cut cut : cutArr)
-      {
-         jArr.add(cut.toJsonObject());
-      }
-
-      return jArr.toString();
-   }
-
-
-
-   private MCutResult.Cut doFileByIdWithErr(String id, Pos pos, Band band, Time time, Pol pol, String pixels,
-         boolean countNullValues/*, Subsurvey[] subsurveys*/)
-   {
-      LOGGER.fine("trace");
-
-      MCutResult mCutResult = new MCutResult();
-      MCutResult.Cut cut = mCutResult.new Cut(/* FIXME eventually add here new Inputs(id, pos,..) */);
-
-      try
-      {
-         CutResult cutResult = doFileById(id,
-               pos,  band, time,  pol, pixels,
-               countNullValues/*,  subsurveys*/);
-
-         cut.content     = cutResult.fileName;
-         cut.contentType = MCutResult.Cut.ContentType.FILENAME;
-      }
-      catch(MultiValuedParamNotSupported ex) 
-      {
-         cut.content = "MultiValuedParamNotSupported: " + ex.getMessage();
-         cut.contentType = MCutResult.Cut.ContentType.BAD_REQUEST;
-         LOGGER.warning(cut.content);
-      }
-      catch(IllegalArgumentException ex) 
-      {
-         cut.content = "IllegalArgumentException: " + ex.getMessage();
-         cut.contentType = MCutResult.Cut.ContentType.BAD_REQUEST;
-         LOGGER.warning(cut.content);
-      }
-      catch(Exception ex) 
-      {
-         cut.content     = "Exception: " + ex.getMessage();
-         cut.contentType = MCutResult.Cut.ContentType.SERVICE_ERROR;
-         LOGGER.severe(cut.content);
-         ex.printStackTrace();
-      }
-
-      return cut;
-   }
-
-
-
-  /*
-      <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-compress</artifactId>
-      <version>1.20</version>
-      </dependency>
-
-      import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
-      import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
-      import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
-  */
-   private static void createTarGzipFiles(List<Path> paths, Path output)
-         throws IOException
-      {
-         try (OutputStream fOut = Files.newOutputStream(output);
-               BufferedOutputStream buffOut = new BufferedOutputStream(fOut);
-               GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(buffOut);
-               TarArchiveOutputStream tOut = new TarArchiveOutputStream(gzOut))
-         {
-            for (Path path : paths)
-            {
-               if (!Files.isRegularFile(path))
-               {
-                  throw new IOException("Must be regular file, but was : " + path.toString());
-               }
-
-               TarArchiveEntry tarEntry = new TarArchiveEntry(
-                     path.toFile(),
-                     path.getFileName().toString());
-
-               tOut.putArchiveEntry(tarEntry);
-
-               // copy file to TarArchiveOutputStream
-               Files.copy(path, tOut);
-
-               tOut.closeArchiveEntry();
-            }
-
-            tOut.finish();
-         }
-      }
 
 }
 
diff --git a/data-access/servlet/src/main/java/mcutout/webapi/UWSMCutoutWork.java b/data-access/servlet/src/main/java/mcutout/webapi/UWSMCutoutWork.java
index f5843301190881fa03968092ccfb93db1009b2f0..6f42d1e04cb3edb1f43ed1c8058ff126a8cf8dca 100644
--- a/data-access/servlet/src/main/java/mcutout/webapi/UWSMCutoutWork.java
+++ b/data-access/servlet/src/main/java/mcutout/webapi/UWSMCutoutWork.java
@@ -10,6 +10,8 @@ import java.io.OutputStreamWriter;
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
 
+import org.apache.commons.io.FileUtils;
+
 import uws.UWSException;
 import uws.job.ErrorType;
 import uws.job.JobThread;
@@ -78,7 +80,10 @@ public class UWSMCutoutWork extends JobThread
          }
          String reqJsonString = jsonStringBuffer.toString();
 
-         MCutResult mresult = vlkb.doMCutout(reqJsonString);
+			String workDir = settings.fitsPaths.cutouts() + "/" + job.getJobId();
+			FileUtils.forceMkdir(new File(workDir));
+
+         MCutResult mresult = vlkb.doMCutout(reqJsonString, workDir);
 
 			logger.logThread(LogLevel.INFO, this, "Prepare Result",
 					" job:requestUrl: " +  job.getUrl().getRequestURL(), null);
@@ -88,9 +93,11 @@ public class UWSMCutoutWork extends JobThread
 
 			// delete cut-files (were published/copied to uws-file store) 
 
-			mresult.deleteResJson();
-			mresult.deleteCutFiles();
+			//mresult.deleteResJson();
+			//mresult.deleteCutFiles();
 
+			FileUtils.deleteDirectory(new File(workDir));
+			//FileUtils.deleteQuietly(new File(workDir));// FIXME Never throws except. leaves the dir there if error
 
 			/* FIXME here was uws-check is-job-Interrupted */
 		}
@@ -104,19 +111,18 @@ public class UWSMCutoutWork extends JobThread
 
 	private void publishOnEndpoint(String epName, String mimeType, String absPathname)
 		throws FileNotFoundException, IOException, UWSException
-	{
-		Result result = new Result(epName, "none", null, false);
-		result.setMimeType(mimeType);
-
-		File downloadFile = new File(absPathname);
-		FileInputStream fileInput = new FileInputStream(downloadFile);
-
-		OutputStream resOutputStream = getResultOutput(result);
-		fileInput.transferTo(resOutputStream);
-
-		publishResult(result);
-
-		downloadFile.delete();
-	}
+		{
+			Result result = new Result(epName, "none", null, false);
+			result.setMimeType(mimeType);
+
+			File downloadFile = new File(absPathname);
+			try(FileInputStream fileInput = new FileInputStream(downloadFile);
+					OutputStream resOutputStream = getResultOutput(result))
+			{
+				fileInput.transferTo(resOutputStream);
+				publishResult(result);
+			}
+			downloadFile.delete();
+		}
 
 }
diff --git a/data-access/servlet/src/main/java/vlkb/Vlkb.java b/data-access/servlet/src/main/java/vlkb/Vlkb.java
index 3302a40dbef92b376b490a463d8cd0f7e8992c47..1bde2e778c5d8153e308561543758c70c6e9b23d 100644
--- a/data-access/servlet/src/main/java/vlkb/Vlkb.java
+++ b/data-access/servlet/src/main/java/vlkb/Vlkb.java
@@ -15,12 +15,13 @@ public interface Vlkb
 {
    public CutResult doFile(String relPathname, int hdunum,
          Pos pos, Band band, Time time, Pol pol, String pixels,
-         boolean countNullValues, FitsCard[] extraCards)
+         boolean countNullValues, FitsCard[] extraCards,
+			String cutAbsPathname)
          throws IOException, InterruptedException;
 
 
 
-   public MCutResult doMCutout(String jdlJson)
+   public MCutResult doMCutout(String jdlJson, String workDir)
       throws IOException, InterruptedException;
 
 
diff --git a/data-access/servlet/src/main/java/vlkb/VlkbAmqp.java b/data-access/servlet/src/main/java/vlkb/VlkbAmqp.java
index 0184865308de4475c1e981d5a41b3a9e9b118508..dddeec9236db94ff20a4254d958b6c49e4301976 100644
--- a/data-access/servlet/src/main/java/vlkb/VlkbAmqp.java
+++ b/data-access/servlet/src/main/java/vlkb/VlkbAmqp.java
@@ -79,7 +79,7 @@ class VlkbAmqp implements Vlkb
 
    public CutResult doFile(String relPathname, int hdunum,
       Pos pos, Band band, Time time, Pol pol, String pixels,
-      boolean countNullValues, FitsCard[] extraCards)
+      boolean countNullValues, FitsCard[] extraCards, String dummyCutAbsPathname)
          throws IOException, InterruptedException
       {
          LOGGER.fine("trace: " + pos.toString() );
@@ -134,7 +134,7 @@ class VlkbAmqp implements Vlkb
          final String DEFAULT_TIME_SYSTEM = "MJD_UTC"; // FIXME take from confif file
 
          CutResult cutResult = doFile(relPathname, hdunum, pos, band, time, pol, pixels,
-               countNullValues, extraCards);
+               countNullValues, extraCards, null);
 
          return cutResult;
       }
@@ -145,7 +145,7 @@ class VlkbAmqp implements Vlkb
    ///////////////////////////////////////////////////////////////////////////////////
 
 
-   public MCutResult doMCutout(String jdlJson)
+   public MCutResult doMCutout(String jdlJson, String workDir)
          throws IOException
       {
          LOGGER.fine("trace");