diff --git a/src/main/java/cz/it4i/qcmp/DataCompressor.java b/src/main/java/cz/it4i/qcmp/DataCompressor.java
index 6061522ccd47345eeeed4760d3b80e9f8c9030f8..fa30b58a88c2804d6319e062401ceb87c8d0f882 100644
--- a/src/main/java/cz/it4i/qcmp/DataCompressor.java
+++ b/src/main/java/cz/it4i/qcmp/DataCompressor.java
@@ -2,6 +2,7 @@ package cz.it4i.qcmp;
 
 import cz.it4i.qcmp.benchmark.CompressionBenchmark;
 import cz.it4i.qcmp.cache.QuantizationCacheManager;
+import cz.it4i.qcmp.cache.QvcFileReader;
 import cz.it4i.qcmp.cli.CliConstants;
 import cz.it4i.qcmp.cli.CompressionOptionsCLIParser;
 import cz.it4i.qcmp.cli.CustomFunctionBase;
@@ -9,6 +10,7 @@ import cz.it4i.qcmp.cli.functions.DebugFunction;
 import cz.it4i.qcmp.compression.ImageCompressor;
 import cz.it4i.qcmp.compression.ImageDecompressor;
 import cz.it4i.qcmp.fileformat.FileExtensions;
+import cz.it4i.qcmp.fileformat.IQvcFile;
 import org.apache.commons.cli.*;
 
 import java.io.IOException;
@@ -36,24 +38,24 @@ public class DataCompressor {
             return;
         }
 
-        final CompressionOptionsCLIParser compressionOptionsCLIParsed = new CompressionOptionsCLIParser(cmd);
+        final CompressionOptionsCLIParser parsedOptions = new CompressionOptionsCLIParser(cmd);
         // NOTE(Moravec): From this point we need to dispose of possible existing SCIFIO context.
-        if (compressionOptionsCLIParsed.parseError()) {
-            System.err.println(compressionOptionsCLIParsed.getParseError());
+        if (parsedOptions.parseError()) {
+            System.err.println(parsedOptions.getParseError());
             ScifioWrapper.dispose();
             return;
         }
 
-        if (compressionOptionsCLIParsed.isVerbose()) {
-            System.out.println(compressionOptionsCLIParsed.report());
+        if (parsedOptions.isVerbose()) {
+            System.out.println(parsedOptions.report());
         }
 
-        switch (compressionOptionsCLIParsed.getMethod()) {
+        switch (parsedOptions.getMethod()) {
             case Compress: {
                 final String label =
-                        compressionOptionsCLIParsed.getQuantizationType().toString() + " " + compressionOptionsCLIParsed.getQuantizationVector().toString();
+                        parsedOptions.getQuantizationType().toString() + " " + parsedOptions.getQuantizationVector().toString();
                 //                final Stopwatch stopwatch = Stopwatch.startNew();
-                final ImageCompressor compressor = new ImageCompressor(compressionOptionsCLIParsed);
+                final ImageCompressor compressor = new ImageCompressor(parsedOptions);
                 if (!compressor.compress()) {
                     System.err.println("Errors occurred during compression.");
                 }
@@ -66,7 +68,7 @@ public class DataCompressor {
             break;
             case Decompress: {
                 //                final Stopwatch stopwatch = Stopwatch.startNew();
-                final ImageDecompressor decompressor = new ImageDecompressor(compressionOptionsCLIParsed);
+                final ImageDecompressor decompressor = new ImageDecompressor(parsedOptions);
                 if (!decompressor.decompressToFile()) {
                     System.err.println("Errors occurred during decompression.");
                 }
@@ -78,11 +80,11 @@ public class DataCompressor {
             break;
 
             case Benchmark: {
-                CompressionBenchmark.runBenchmark(compressionOptionsCLIParsed);
+                CompressionBenchmark.runBenchmark(parsedOptions);
             }
             break;
             case TrainCodebook: {
-                final ImageCompressor compressor = new ImageCompressor(compressionOptionsCLIParsed);
+                final ImageCompressor compressor = new ImageCompressor(parsedOptions);
                 if (!compressor.trainAndSaveCodebook()) {
                     System.err.println("Errors occurred during training/saving of codebook.");
                 }
@@ -94,7 +96,7 @@ public class DataCompressor {
                 // final CustomFunctionBase customFunction = new MeasurePlaneErrorFunction(parsedCliOptions);
                 // final CustomFunctionBase customFunction = new EntropyCalculation(compressionOptionsCLIParsed);
                 // final CustomFunctionBase cf = new CalculateDifference(compressionOptionsCLIParsed);
-                final CustomFunctionBase cf = new DebugFunction(compressionOptionsCLIParsed);
+                final CustomFunctionBase cf = new DebugFunction(parsedOptions);
                 if (!cf.run()) {
                     System.err.println("Errors occurred during custom function.");
                 }
@@ -106,11 +108,11 @@ public class DataCompressor {
             }
             break;
             case InspectFile: {
-                if (compressionOptionsCLIParsed.getInputDataInfo().getFilePath().endsWith(FileExtensions.CACHE_FILE_EXT)) {
-                    QuantizationCacheManager.inspectCacheFile(compressionOptionsCLIParsed.getInputDataInfo().getFilePath(),
-                                                              compressionOptionsCLIParsed.isVerbose());
+                if (parsedOptions.getInputDataInfo().getFilePath().endsWith(FileExtensions.CACHE_FILE_EXT)) {
+                    QuantizationCacheManager.inspectCacheFile(parsedOptions.getInputDataInfo().getFilePath(),
+                                                              parsedOptions.isVerbose());
                 } else {
-                    final ImageDecompressor decompressor = new ImageDecompressor(compressionOptionsCLIParsed);
+                    final ImageDecompressor decompressor = new ImageDecompressor(parsedOptions);
                     try {
                         System.out.println(decompressor.inspectCompressedFile());
                     } catch (final IOException e) {
@@ -121,7 +123,41 @@ public class DataCompressor {
                 }
             }
             break;
+            case Convert: {
+                final boolean inPlace = parsedOptions.getOutputFilePath() == null;
+                // TODO(Moravec): Maybe replace with generic reader which can determine file type based on magic value and not an extension.
+                if (parsedOptions.getInputDataInfo().getFilePath().endsWith(FileExtensions.CACHE_FILE_EXT)) {
+                    IQvcFile cacheFile = null;
+                    try {
+                        cacheFile = QvcFileReader.readCacheFile(parsedOptions.getInputDataInfo().getFilePath());
+                    } catch (final IOException e) {
+                        System.err.println("Unable to read QVC file. Error: " + e.getMessage());
+                        exitApplication(1);
+                    }
+                    try {
+                        assert (cacheFile != null);
+                        cacheFile.convertToNewerVersion(inPlace, parsedOptions.getInputDataInfo().getFilePath(),
+                                                        parsedOptions.getOutputFilePath());
+                    } catch (final IOException e) {
+                        System.err.println("Unable to convert specified QVC file. Error: " + e.getMessage());
+                        exitApplication(1);
+                    }
+
+                    if (parsedOptions.isVerbose()) {
+                        System.err.println("Qvc file is converted.");
+                    }
+
+                } else {
+                    System.err.println("Qcmp file conversion isn't supported yet");
+                }
+            }
+            break;
         }
         ScifioWrapper.dispose();
     }
+
+    private static void exitApplication(final int exitCode) {
+        ScifioWrapper.dispose();
+        System.exit(exitCode);
+    }
 }
diff --git a/src/main/java/cz/it4i/qcmp/cli/CliConstants.java b/src/main/java/cz/it4i/qcmp/cli/CliConstants.java
index 9d327490e1e96c86c6a84302cbaed951835cf983..02a9f91b48666badc5ad5c9c871537b44ba3ac74 100644
--- a/src/main/java/cz/it4i/qcmp/cli/CliConstants.java
+++ b/src/main/java/cz/it4i/qcmp/cli/CliConstants.java
@@ -30,6 +30,9 @@ public class CliConstants {
     public static final String CUSTOM_FUNCTION_SHORT = "cf";
     public static final String CUSTOM_FUNCTION_LONG = "custom-function";
 
+    public static final String CONVERT_SHORT = "conv";
+    public static final String CONVERT_LONG = "convert";
+
     public static final String BITS_SHORT = "b";
     public static final String BITS_LONG = "bits";
 
@@ -72,6 +75,10 @@ public class CliConstants {
                                          CliConstants.INSPECT_LONG,
                                          false,
                                          "Inspect the compressed file"));
+        methodGroup.addOption(new Option(CliConstants.CONVERT_SHORT,
+                                         CliConstants.CONVERT_LONG,
+                                         false,
+                                         "Convert input file to new version of custom file format"));
 
         methodGroup.addOption(new Option(CliConstants.BENCHMARK_SHORT,
                                          CliConstants.BENCHMARK_LONG,
diff --git a/src/main/java/cz/it4i/qcmp/cli/CompressionOptionsCLIParser.java b/src/main/java/cz/it4i/qcmp/cli/CompressionOptionsCLIParser.java
index 6cf18049d6e2b1934870eb9b4a781aded9019b85..c30fb4d5b807ddca0b0bfb184cbaeb532161a211 100644
--- a/src/main/java/cz/it4i/qcmp/cli/CompressionOptionsCLIParser.java
+++ b/src/main/java/cz/it4i/qcmp/cli/CompressionOptionsCLIParser.java
@@ -390,6 +390,8 @@ public class CompressionOptionsCLIParser extends CompressionOptions implements C
             method = ProgramMethod.InspectFile;
         } else if (cmd.hasOption(CliConstants.CUSTOM_FUNCTION_LONG)) {
             method = ProgramMethod.CustomFunction;
+        } else if (cmd.hasOption(CliConstants.CONVERT_LONG)) {
+            method = ProgramMethod.Convert;
         } else {
             parseErrorOccurred = true;
             errorBuilder.append("No program method was matched\n");
@@ -412,31 +414,7 @@ public class CompressionOptionsCLIParser extends CompressionOptions implements C
     public String report() {
         final StringBuilder sb = new StringBuilder();
 
-        sb.append("Method: ");
-        switch (method) {
-            case Compress:
-                sb.append("Compress\n");
-                break;
-            case Decompress:
-                sb.append("Decompress\n");
-                break;
-            case Benchmark:
-                sb.append("Benchmark\n");
-                break;
-            case TrainCodebook:
-                sb.append("TrainCodebook\n");
-                break;
-            case PrintHelp:
-                sb.append("PrintHelp\n");
-                break;
-            case CustomFunction:
-                sb.append("CustomFunction\n");
-                break;
-            case InspectFile:
-                sb.append("InspectFile\n");
-                break;
-        }
-
+        sb.append("Method: ").append(method).append('\n');
 
         if (hasQuantizationType(method)) {
             sb.append("Quantization type: ");
@@ -470,7 +448,6 @@ public class CompressionOptionsCLIParser extends CompressionOptions implements C
         }
 
         if (hasQuantizationType(method)) {
-
             sb.append("Input image dims: ").append(getInputDataInfo().getDimensions().toString()).append('\n');
         }
         if (getInputDataInfo().isPlaneIndexSet()) {
diff --git a/src/main/java/cz/it4i/qcmp/cli/ProgramMethod.java b/src/main/java/cz/it4i/qcmp/cli/ProgramMethod.java
index 73d3abdd417bb37671f4984550b452703172cc4a..fd83e49716ad6c74361a64fb645c906c94d8706c 100644
--- a/src/main/java/cz/it4i/qcmp/cli/ProgramMethod.java
+++ b/src/main/java/cz/it4i/qcmp/cli/ProgramMethod.java
@@ -7,5 +7,6 @@ public enum ProgramMethod {
     TrainCodebook,
     PrintHelp,
     CustomFunction,
-    InspectFile
+    InspectFile,
+    Convert
 }
diff --git a/src/main/java/cz/it4i/qcmp/fileformat/IQvcHeader.java b/src/main/java/cz/it4i/qcmp/fileformat/IQvcHeader.java
index b1a752f690a7a1b05ec7c3e245229a859a2d23db..fae999d092e365ac77588ae488fafd6472dcbff0 100644
--- a/src/main/java/cz/it4i/qcmp/fileformat/IQvcHeader.java
+++ b/src/main/java/cz/it4i/qcmp/fileformat/IQvcHeader.java
@@ -10,4 +10,6 @@ public interface IQvcHeader extends IFileHeader {
     int getCodebookSize();
 
     V3i getVectorDim();
+
+    String getTrainFileName();
 }
diff --git a/src/main/java/cz/it4i/qcmp/fileformat/QvcHeaderV1.java b/src/main/java/cz/it4i/qcmp/fileformat/QvcHeaderV1.java
index 4d0027b60e1c71827a70156fffe6d293bc20ad4b..34399f17e90e6259dd646ffaa6f2dd3b57e6b157 100644
--- a/src/main/java/cz/it4i/qcmp/fileformat/QvcHeaderV1.java
+++ b/src/main/java/cz/it4i/qcmp/fileformat/QvcHeaderV1.java
@@ -155,18 +155,22 @@ public class QvcHeaderV1 implements IQvcHeader {
         this.trainFileNameSize = this.trainFileName.length();
     }
 
+    @Override
     public QuantizationType getQuantizationType() {
         return quantizationType;
     }
 
+    @Override
     public int getCodebookSize() {
         return codebookSize;
     }
 
+    @Override
     public int getBitsPerCodebookIndex() {
         return (int) Utils.log2(codebookSize);
     }
 
+    @Override
     public String getTrainFileName() {
         return trainFileName;
     }
@@ -183,6 +187,7 @@ public class QvcHeaderV1 implements IQvcHeader {
         return vectorSizeZ;
     }
 
+    @Override
     public V3i getVectorDim() {
         return new V3i(vectorSizeX, vectorSizeY, vectorSizeZ);
     }
diff --git a/src/main/java/cz/it4i/qcmp/fileformat/SqQvcFile.java b/src/main/java/cz/it4i/qcmp/fileformat/SqQvcFile.java
index df75deac894302e717ad27588a8eaf81acec90e1..d90ec8946c93c562884d7d71af5a8e3b17692354 100644
--- a/src/main/java/cz/it4i/qcmp/fileformat/SqQvcFile.java
+++ b/src/main/java/cz/it4i/qcmp/fileformat/SqQvcFile.java
@@ -1,5 +1,6 @@
 package cz.it4i.qcmp.fileformat;
 
+import cz.it4i.qcmp.cache.QvcFileWriter;
 import cz.it4i.qcmp.huffman.HuffmanNode;
 import cz.it4i.qcmp.huffman.HuffmanTreeBuilder;
 import cz.it4i.qcmp.io.InBitStream;
@@ -88,22 +89,18 @@ public class SqQvcFile implements IQvcFile {
         codebook = new SQCodebook(centroids, huffmanRoot);
     }
 
-    private void convertQvcFromV1ToV2(final String outputFilePath) {
-
-    }
 
     @Override
-    public void convertToNewerVersion(final boolean inPlace, final String inputPath, final String outputPath) {
-        final int headerVersion = header.getHeaderVersion();
+    public void convertToNewerVersion(final boolean inPlace, final String inputPath, final String outputPath) throws IOException {
         if (!inPlace && (outputPath == null || outputPath.isEmpty())) {
             System.err.println("InPlace conversion wasn't specified nor the output file path.");
             return;
         }
-        if (headerVersion == 1) {
-            convertQvcFromV1ToV2(inPlace ? inputPath : outputPath);
-        } else {
-            System.err.printf("Version %d is already the newest version of QVC file.\n", headerVersion);
+        if (header.getHeaderVersion() == 2) {
+            System.err.print("Version 2 is already the newest version of QVC file.\n");
+            return;
         }
+        QvcFileWriter.writeSqCacheFile(inPlace ? inputPath : outputPath, header.getTrainFileName(), codebook);
     }
 
     @Override
diff --git a/src/main/java/cz/it4i/qcmp/fileformat/VqQvcFile.java b/src/main/java/cz/it4i/qcmp/fileformat/VqQvcFile.java
index 83dcc6af614a66072aa453af63c6d659a06b37ca..b7ad419c6853c93a09051841fe7826be0ddfd7b3 100644
--- a/src/main/java/cz/it4i/qcmp/fileformat/VqQvcFile.java
+++ b/src/main/java/cz/it4i/qcmp/fileformat/VqQvcFile.java
@@ -1,5 +1,6 @@
 package cz.it4i.qcmp.fileformat;
 
+import cz.it4i.qcmp.cache.QvcFileWriter;
 import cz.it4i.qcmp.huffman.HuffmanNode;
 import cz.it4i.qcmp.huffman.HuffmanTreeBuilder;
 import cz.it4i.qcmp.io.InBitStream;
@@ -97,8 +98,16 @@ public class VqQvcFile implements IQvcFile {
     }
 
     @Override
-    public void convertToNewerVersion(final boolean inPlace, final String inputPath, final String outputPath) {
-        assert false : "NOT IMPLEMENTED YET";
+    public void convertToNewerVersion(final boolean inPlace, final String inputPath, final String outputPath) throws IOException {
+        if (!inPlace && (outputPath == null || outputPath.isEmpty())) {
+            System.err.println("InPlace conversion wasn't specified nor the output file path.");
+            return;
+        }
+        if (header.getHeaderVersion() == 2) {
+            System.err.print("Version 2 is already the newest version of QVC file.\n");
+            return;
+        }
+        QvcFileWriter.writeVqCacheFile(inPlace ? inputPath : outputPath, header.getTrainFileName(), codebook);
     }
 
     @Override
@@ -111,7 +120,5 @@ public class VqQvcFile implements IQvcFile {
             }
             builder.append("\n- - - - - - - - - - - - - - - - - - - - - - - - -\n");
         }
-
-
     }
 }