Complete Makeover
authorMaximilian Quellmalz <maximilian.quellmalz@mailbox.tu-dresden.de>
Thu, 11 Dec 2014 20:27:12 +0000 (21:27 +0100)
committerMaximilian Quellmalz <maximilian.quellmalz@mailbox.tu-dresden.de>
Thu, 11 Dec 2014 20:27:12 +0000 (21:27 +0100)
commandline support
codec configuration from ini
interactive codec configuration

Splitter-ng-filesplitter/.classpath
Splitter-ng-filesplitter/build.xml
Splitter-ng-filesplitter/filesplitter
Splitter-ng-filesplitter/filesplitter-x
Splitter-ng-filesplitter/filesplitter.ini [new file with mode: 0644]
Splitter-ng-filesplitter/lib/ini4j-0.5.2.jar [new file with mode: 0644]
Splitter-ng-filesplitter/src/Filesplitter.java
Splitter-ng-filesplitter/src/Test.java [new file with mode: 0644]

index 65cf4e2..29ca0b7 100644 (file)
@@ -3,5 +3,6 @@
        <classpathentry kind="src" path="src"/>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
        <classpathentry combineaccessrules="false" kind="src" path="/Splitter-ng"/>
+       <classpathentry kind="lib" path="lib/ini4j-0.5.2.jar"/>
        <classpathentry kind="output" path="bin"/>
 </classpath>
index 8e21b77..f0f4593 100644 (file)
@@ -11,6 +11,9 @@
        <path id="Splitter-ng-filesplitter.classpath">
                <pathelement location="bin" />
                <pathelement location="lib" />
+               <fileset dir="lib">
+                       <include name="*.jar"/>
+               </fileset>
                <path refid="Splitter-ng.classpath" />
        </path>
        <target name="init">
@@ -66,6 +69,7 @@
        <target name="makejar" depends="build" description="Create a jar for the project">
                <jar jarfile="bin/${ant.project.name}.jar">
                        <fileset dir="bin" includes="**/*.class" />
+                       <zipgroupfileset dir="lib" includes="*.jar" />
                        <manifest>
                                <attribute name="Main-Class" value="Filesplitter" />
                                <attribute name="Class-Path" value="lib/Splitter-ng.jar"/>
index a85401a..a1a6e2f 100755 (executable)
@@ -2,5 +2,5 @@
 #Nicht mehr nötig wenn jerasure im plugin-jar ist
 #PWD="`dirname \`readlink -f $0\``"
 #cd $PWD
-LD_LIBRARY_PATH="/tmp/:$PWD/plugin/" java -jar Splitter-ng-filesplitter.jar
+LD_LIBRARY_PATH="/tmp/:$PWD/plugin/" java -jar Splitter-ng-filesplitter.jar "$@"
 #java -jar Splitter-ng-filesplitter.jar
index b9d9ed5..1134c46 100755 (executable)
@@ -1,3 +1,3 @@
 #!/bin/bash
 
-x-terminal-emulator -e ./filesplitter
+x-terminal-emulator -e ./filesplitter "$@"
diff --git a/Splitter-ng-filesplitter/filesplitter.ini b/Splitter-ng-filesplitter/filesplitter.ini
new file mode 100644 (file)
index 0000000..3425269
--- /dev/null
@@ -0,0 +1,8 @@
+[JigDFS/crs]
+chunksize = 16
+m = 5
+k = 5
+
+[JigDFS/crs_MetadataTemplate]
+fragmentsize = 4096
+
diff --git a/Splitter-ng-filesplitter/lib/ini4j-0.5.2.jar b/Splitter-ng-filesplitter/lib/ini4j-0.5.2.jar
new file mode 100644 (file)
index 0000000..27e5ddc
Binary files /dev/null and b/Splitter-ng-filesplitter/lib/ini4j-0.5.2.jar differ
index e95aac5..b4fc770 100644 (file)
@@ -1,17 +1,24 @@
+import java.io.File;
 import java.io.IOException;
 import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
+import java.nio.file.LinkOption;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Scanner;
+import java.util.Set;
 import java.util.TreeMap;
 
+import org.ini4j.Ini;
+import org.ini4j.Profile.Section;
+
 import splitterng.CodingTask;
 import splitterng.DecodingTask;
 import splitterng.EncodingTask;
@@ -21,275 +28,87 @@ import splitterng.plugin.CodecDescription;
 import splitterng.plugin.PluginDescription;
 
 public class Filesplitter implements SplitterCallback {
+       /*
+        * public static final String ANSI_RESET = ""; public static final String
+        * ANSI_BLACK = ""; public static final String ANSI_RED = ""; public static
+        * final String ANSI_GREEN = ""; public static final String ANSI_YELLOW =
+        * ""; public static final String ANSI_BLUE = ""; public static final String
+        * ANSI_PURPLE = ""; public static final String ANSI_CYAN = ""; public
+        * static final String ANSI_WHITE = ""; public static final String ANSI_BOLD
+        * = "";
+        */
+       public static final String ANSI_RESET = "\u001B[0m";
+       public static final String ANSI_BLACK = "\u001B[30m";
+       public static final String ANSI_RED = "\u001B[31m";
+       public static final String ANSI_GREEN = "\u001B[32m";
+       public static final String ANSI_YELLOW = "\u001B[33m";
+       public static final String ANSI_BLUE = "\u001B[34m";
+       public static final String ANSI_PURPLE = "\u001B[35m";
+       public static final String ANSI_CYAN = "\u001B[36m";
+       public static final String ANSI_WHITE = "\u001B[37m";
+       public static final String ANSI_BOLD = "\u001B[1m";
+
+       public Ini config;
+       public static String CONFIGFILE = "filesplitter.ini";
 
-       private Collection<Splitter> splitters = new LinkedList<Splitter>();
        private List<CodingTask> finished_encoding_task = new LinkedList<CodingTask>();
        private List<CodingTask> finished_decoding_task = new LinkedList<CodingTask>();
        private List<CodingTask> running_tasks = new LinkedList<CodingTask>();
-
+       private List<String> codeclist = new LinkedList<String>();
+       private List<String> codeclist_configured = new LinkedList<String>();
+       private List<String> codeclist_failed = new LinkedList<String>();
        // in der Map werden die Metadaten-vorlage für jeden Codec gespeichert
+       private List<Splitter> splitters = new LinkedList<Splitter>();
        private Map<Splitter, Map<String, Object>> splitter_metadata_map = new HashMap<Splitter, Map<String, Object>>();
 
        public static void main(String[] args) throws InterruptedException {
                Filesplitter filesplitter = new Filesplitter();
-               filesplitter.run();
+               filesplitter.run(args);
 
                // Thread.sleep(50000);
                // System.exit(0);
        }
 
-       public void run() {
+       public String readCommandline() {
+               return readCommandline("",false);
+       }
+       public String readCommandline(String string) {
+               return readCommandline(string,false);
+       }
+       public String readCommandline(boolean allowblanklines) {
+               return readCommandline("",allowblanklines);
+       }
+       public String readCommandline(String string ,boolean allowblanklines) {
+               Scanner in;
+               String line = null;
+               in = new Scanner(System.in);
+               while (line == null || (!allowblanklines && line.isEmpty())) {
+                       System.out.print(ANSI_BOLD +string+ ANSI_RESET);
+                       line = in.nextLine();
+               }
+               return line;
 
-               System.out.println("Splitter Plugins");
-               // Optional: Anfrage, welche Plugins geladen sind
-               for (PluginDescription p : Splitter.getPluginDescriptions()) {
-                       System.out.println("---------------------------------------------\n" + p.getPluginID() + "\t"
-                                       + p.getPluginName());
-                       // Optional: Aus jeder Plugindescription die Verfügbaren Codecs
-                       // auslesen
-                       for (CodecDescription c : p.getCodecDescriptions()) {
-                               System.out.println("\t|---------------------------------------------\n\t|" + c.getCodecID() + "\t"
-                                               + c.getCodecDescriptionText());
-                               Map<String, Integer[]> codecParameterMinMax = c
-                                               .getCodecParameterMinMax();
-                               for (Entry<String, Integer[]> e : codecParameterMinMax
-                                               .entrySet()) {
-                                       System.out.println("\t|\t" + e.getKey() + "\tmin:"
-                                                       + e.getValue()[0] + "  max:" + e.getValue()[1] + " default: " + c.getCodecParameterDefaults().get(e.getKey()));
-                               }
-                               // Wenn hier eine Konfiguration für eine plugin-codec
-                               // Kombination vorhanden ist, wird der Splitter initialisiert.
-                               Map<String, Integer> codecParameter;
-                               Splitter splitter;
-                               switch (p.getPluginID() + "/" + c.getCodecID()) {
-///-----------------------------------------------------------------------------------------------
-///-----------------------------------------------------------------------------------------------
-///-----------------------------------------------------------------------------------------------
-///-----------------------------------------------------------------------------------------------
-                               case "jerasure/JerasureCauchyGood":
-                                       // Codecparameter Bauen
-                                       codecParameter = new TreeMap<String, Integer>();
-                                       codecParameter.put("k", 2);
-                                       codecParameter.put("m", 2);
-                                       //codecParameter.put("w", 8);
-                                       //codecParameter.put("packetsize", 8);
-                                       System.out.println("\t\tinitialisiere mit" + " k="
-                                                       + codecParameter.get("k") + " m="
-                                                       + codecParameter.get("m") + " w="
-                                                       + codecParameter.get("w") + " packetsize="
-                                                       + codecParameter.get("packetsize"));
-                                       // Splitter mit Plugin-ID CodecID und codecparametern
-                                       // initialisieren
-                                       Splitter splitterjerasure = new Splitter(p.getPluginID(), c.getCodecID(),
-                                                       codecParameter);
-                                       splitters.add(splitterjerasure);
-                                       
-                                       // Metadaten bauen vorlage
-                                       Map<String, Object> metadatajerasure = new TreeMap<String, Object>();
-                                       metadatajerasure.put("fragmentsize", (int) 64);
-                                       // Beleiebige weitere Metadaten
-                                       
-                                       splitter_metadata_map.put(splitterjerasure, metadatajerasure);
-                                       break;
-///-----------------------------------------------------------------------------------------------
-                               case "jerasure/JerasureReedSolomon":
-                                       // Codecparameter Bauen
-                                       Map<String, Integer> codecParameter1 = new TreeMap<String, Integer>();
-                                       codecParameter1.put("k", 3);
-                                       codecParameter1.put("m", 3);
-                                       //codecParameter1.put("w", 16);
-                                       //codecParameter1.put("packetsize", 64);
-                                       System.out.println("\t\tinitialisiere mit" + " k="
-                                                       + codecParameter1.get("k") + " m="
-                                                       + codecParameter1.get("m") + " w="
-                                                       + codecParameter1.get("w") + " packetsize="
-                                                       + codecParameter1.get("packetsize"));
-                                       // Splitter mit Plugin-ID CodecID und codecparametern
-                                       // initialisieren
-                                       Splitter splitterjerasure1 = new Splitter(p.getPluginID(), c.getCodecID(),
-                                                       codecParameter1);
-                                       splitters.add(splitterjerasure1);
-                                       
-                                       // Metadaten bauen vorlage
-                                       Map<String, Object> metadatajerasure1 = new TreeMap<String, Object>();
-                                       metadatajerasure1.put("fragmentsize", (int) 40960);
-                                       // Beleiebige weitere Metadaten
-                                       
-                                       splitter_metadata_map.put(splitterjerasure1, metadatajerasure1);
-                                       break;
-///-----------------------------------------------------------------------------------------------
-                               case "jerasure/JerasureLiber8tion":
-                                       // Codecparameter Bauen
-                                       Map<String, Integer> codecParameter2 = new TreeMap<String, Integer>();
-                                       codecParameter2.put("k", 3);
-                                       codecParameter2.put("m", 2);
-                                       codecParameter2.put("packetsize", 64);
-                                       System.out.println("\t\tinitialisiere mit"
-                                                       + " k=" + codecParameter2.get("k") 
-                                                       + " m=" + codecParameter2.get("m")
-                                                       + " packetsize=" + codecParameter2.get("packetsize"));
-                                       // Splitter mit Plugin-ID CodecID und codecparametern
-                                       // initialisieren
-                                       Splitter splitterjerasure2 = new Splitter(p.getPluginID(), c.getCodecID(),
-                                                       codecParameter2);
-                                       splitters.add(splitterjerasure2);
-                                       
-                                       // Metadaten bauen vorlage
-                                       Map<String, Object> metadatajerasure2 = new TreeMap<String, Object>();
-                                       metadatajerasure2.put("fragmentsize", (int) 40960);
-                                       // Beleiebige weitere Metadaten
-                                       
-                                       splitter_metadata_map.put(splitterjerasure2, metadatajerasure2);
-                                       break;
-///-----------------------------------------------------------------------------------------------
-                               case "Raid1Plugin/raid1codec":
-                                       // Codecparameter Bauen
-                                       Map<String, Integer> codecParameternoop = new TreeMap<String, Integer>();
-                                       codecParameternoop.put("k", 1);
-                                       codecParameternoop.put("m", 1);
-                                       System.out.println("\t\tinitialisiere mit"
-                                                       + " k=" + codecParameternoop.get("k")
-                                                       + " m=" + codecParameternoop.get("m")
-                                                       );
-                                       // Splitter mit Plugin-ID CodecID und codecparametern
-                                       // initialisieren
-                                       Splitter splitterraid1 = new Splitter(p.getPluginID(), c.getCodecID(),
-                                                       codecParameternoop);
-                                       splitters.add(splitterraid1);
-                                       
-                                       // Metadaten bauen vorlage
-                                       Map<String, Object> metadataraid1 = new TreeMap<String, Object>();
-                                       metadataraid1.put("fragmentsize", (int) 40960);
-                                       // Beleiebige weitere Metadaten
-                                       
-                                       splitter_metadata_map.put(splitterraid1, metadataraid1);
-                                       
-                                       break;
-///-----------------------------------------------------------------------------------------------
-                               case "jsharing/shamir":
-                                       // Codecparameter Bauen
-                                       Map<String, Integer> codecParameterjsharing = new TreeMap<String, Integer>();
-                                       codecParameterjsharing.put("k", 2);
-                                       codecParameterjsharing.put("m", 1);
-                                       System.out.println("\t\tinitialisiere mit k="
-                                                       + codecParameterjsharing.get("k") + " m="
-                                                       + codecParameterjsharing.get("m"));
-
-                                       Splitter splittershamir= new Splitter(p.getPluginID(), c.getCodecID(),
-                                                       codecParameterjsharing);
-                                       splitters.add(splittershamir);
-                                       
-                                       // Metadaten bauen vorlage
-                                       Map<String, Object> metadatashamir = new TreeMap<String, Object>();
-                                       metadatashamir.put("fragmentsize", (int)8);
-                                       // Beleiebige weitere Metadaten
-                                       
-                                       splitter_metadata_map.put(splittershamir, metadatashamir);
-                                       
-                                       break;
-///-----------------------------------------------------------------------------------------------
-                               case "jerasure-java/JerasureJavaCRS":
-                                       // Codecparameter Bauen
-                                       Map<String, Integer> codecParameter11 = new TreeMap<String, Integer>();
-                                       codecParameter11.put("k", 2);
-                                       codecParameter11.put("m", 2);
-                                       //codecParameter11.put("w", 8);
-                                       //codecParameter11.put("packetsize", 8);
-                                       System.out.println("\t\tinitialisiere mit"
-                                                       + " k=" + codecParameter11.get("k")
-                                                       + " m=" + codecParameter11.get("m") 
-                                                       + " w=" + codecParameter11.get("w")
-                                                       + " packetsize=" + codecParameter11.get("packetsize")
-                                                       );
-                                       // Splitter mit Plugin-ID CodecID und codecparametern
-                                       // initialisieren
-                                       Splitter splitterjerasure11 = new Splitter(p.getPluginID(), c.getCodecID(),
-                                                       codecParameter11);
-                                       splitters.add(splitterjerasure11);
-                                       
-                                       // Metadaten bauen vorlage
-                                       Map<String, Object> metadatajerasure11 = new TreeMap<String, Object>();
-                                       metadatajerasure11.put("fragmentsize", (int) 64);
-                                       // Beleiebige weitere Metadaten
-                                       
-                                       splitter_metadata_map.put(splitterjerasure11, metadatajerasure11);
-                                       break;
-///-----------------------------------------------------------------------------------------------
-                                       
-                               case "JigDFS/crs":
-                                       // Codecparameter Bauen
-                                       Map<String, Integer> codecParameter111 = new TreeMap<String, Integer>();
-                                       codecParameter111.put("k", 2);
-                                       codecParameter111.put("m", 1);
-                                       //codecParameter111.put("chunksize", 16);
-                                       System.out.println("\t\tinitialisiere mit" + " k="
-                                                       + codecParameter111.get("k") + " m="
-                                                       + codecParameter111.get("m")
-                                                       + " chunksize=" + codecParameter111.get("chunksize")
-                                                       );
-                                       // Splitter mit Plugin-ID CodecID und codecparametern
-                                       // initialisieren
-                                       Splitter splitterjerasure111 = new Splitter(p.getPluginID(), c.getCodecID(),
-                                                       codecParameter111);
-                                       splitters.add(splitterjerasure111);
-                                       
-                                       // Metadaten bauen vorlage
-                                       Map<String, Object> metadatajerasure111 = new TreeMap<String, Object>();
-                                       metadatajerasure111.put("fragmentsize", (int) 64);
-                                       metadatajerasure111.put("digest", "SHA-256");
-                                       //metadatajerasure111.put("digest", "MD5");
-                                       // Beleiebige weitere Metadaten
-                                       splitter_metadata_map.put(splitterjerasure111, metadatajerasure111);
-                                       break;
-///-----------------------------------------------------------------------------------------------
-                                       
-                               case "bitsplitter/bitsplitter":
-                                       // Codecparameter Bauen
-                                       Map<String, Integer> codecParameter1111 = new TreeMap<String, Integer>();
-                                       codecParameter1111.put("k", 4);
-                                       codecParameter1111.put("m", 0);
-                                       System.out.println("\t\tinitialisiere mit" + " k="
-                                                       + codecParameter1111.get("k") + " m="
-                                                       + codecParameter1111.get("m"));
-                                       // Splitter mit Plugin-ID CodecID und codecparametern
-                                       // initialisieren
-                                       Splitter splitter1111 = new Splitter(p.getPluginID(), c.getCodecID(),
-                                                       codecParameter1111);
-                                       splitters.add(splitter1111);
-                                       
-                                       // Metadaten bauen vorlage
-                                       Map<String, Object> metadata1111 = new TreeMap<String, Object>();
-                                       metadata1111.put("fragmentsize", (int) 409600);
-                                       metadata1111.put("digest", "SHA-1");
-                                       // Beleiebige weitere Metadaten
-                                       
-                                       splitter_metadata_map.put(splitter1111, metadata1111);
-                                       break;
-///-----------------------------------------------------------------------------------------------
-///-----------------------------------------------------------------------------------------------
-///-----------------------------------------------------------------------------------------------
-///-----------------------------------------------------------------------------------------------
-///-----------------------------------------------------------------------------------------------
-                               default:
-                                       try {
-                                               splitter = new Splitter(p.getPluginID(), c.getCodecID(),4,1);
-                                               System.out.println("\t\tDefault Splitter created for: "
-                                                               + p.getPluginID() + "/" + c.getCodecID());                                              
-                                       } catch (Exception e) {
-                                               System.out.println("\t\tNO Splitter created for: "
-                                                               + p.getPluginID() + "/" + c.getCodecID() + "\n" + e.getMessage());      
-                                       }
+       }
 
-                                       break;
-                               }
-                       }
-               }
+       public void run(String[] args) {
+               init_config();
+               print_codecs();
 
-               System.out.println("\nListe der Dateien");
+               println_std("\nProcessing the following files:");
                Path srcDir = Paths.get("srcDir");
-               List<Path> srcFileList = getFileList(srcDir);
+               List<Path> srcFileList = getFileList(srcDir);;
+               for (String s:args){
+                       Path p = Paths.get(s);
+                       if (Files.exists(p, LinkOption.NOFOLLOW_LINKS)){
+                               srcFileList.add(p);
+                       }
+                       else {
+                               println_err("- " + p.toString() + " doesn't exists");
+                       }
+                       
+               }
                for (Path entry : srcFileList) {
-                       System.out.println("- " + entry.toString());
+                       println_std("- " + entry.toString());
                }
 
                // restoreDir anlegen bzw aufräumen
@@ -318,133 +137,121 @@ public class Filesplitter implements SplitterCallback {
                for (Path srcfile : srcFileList) {
                        // ... mit jedem initialisierten Splitter bearbeiten
                        for (Splitter splitter : splitters) {
-                               System.out.println("Encoding: "
-                                               + srcfile
-                                               + "  with "
-                                               + splitter.getCurrentPlugin().getPluginDescription()
-                                                               .getPluginID() + "/"
-                                               + splitter.getCurrentCodecDescription().getCodecID());
-                               try {
-
-                                       Map<String, Object> metadata = new TreeMap<String, Object>();
-                                       
-                                       for (Entry<String, Object> e: splitter_metadata_map.get(splitter).entrySet()){
-                                               metadata.put(e.getKey(), e.getValue());
-                                       }
-                                       
-                                       metadata.put("time_encoding_submitted",
-                                                       System.currentTimeMillis());
-                       
-
-                                       // Hier wird codiert. Der Encodingtask
-                                       EncodingTask task = new EncodingTask(srcfile, Paths
-                                                       .get("splitDir"), this, metadata);
-                                       splitter.encode(task);
-                                       running_tasks.add(task);
-                               } catch (InterruptedException | IOException e) {
-                                       e.printStackTrace();
-                               }
+                               encode(srcfile, splitter);
 
                        }
 
                }
 
-               System.out.println("-----");
-               System.out.println("Alle Aufträge an die Splitter übermittelt");
+               println_info("-----");
+               println_info("All CodingTasks submitted");
 
-               printUsage();
+               println_info("Use 'h' or 'help' to display commands");
+               // printUsage();
 
-               
                // dateien zusammenbauen
-               @SuppressWarnings("resource")
-               Scanner in = new Scanner(System.in);
+               String commandline;
                while (true) {
-                       System.out.print(">>>");
-                       if (!in.hasNext()) System.exit(0);
+                       commandline = readCommandline(">>>");
+                       if (commandline == null) {
+                               println_std("Exit");
+                               System.exit(0);
+                       }
+                       Scanner in = new Scanner(commandline);
                        switch (in.next()) {
                        case "EOF":
                        case "q":
                        case "quit":
                        case "exit":
-                                       System.exit(0);
+                               System.exit(0);
                        case "h":
                        case "help":
                                printUsage();
                                break;
                        case "ls":
-                               switch (in.next()){
-                               case "enc":
-                                       for (CodingTask t : finished_encoding_task) {
-                                               System.out.println(""
-                                                               + finished_encoding_task.lastIndexOf(t) + "\t"
-                                                               + t.getFilePath().getFileName());
-                                       }
-                                       break;
-                               case "dec":
-                                       for (CodingTask t : finished_decoding_task) {
-                                               System.out.println(""
-                                                               + finished_decoding_task.lastIndexOf(t) + "\t"
-                                                               + t.getFilePath().getFileName());
-                                       }
-                                       break;
-                                       
-                               case "frag":
-                                       try {
-                                               for (Entry<Integer, Path> e : finished_encoding_task
-                                                               .get(Integer.parseInt(in.next()))
-                                                               .getFragmentPaths().entrySet()) {
-                                                       System.out.format("\t %-5s %s %s\n", e.getKey(), e
-                                                                       .getValue().toString(), (Files.exists(e
-                                                                       .getValue()) ? "OK" : "Fehlt"));
-                                                       // System.out.println(++"\t"+e.getValue().toString());
+                               if (in.hasNext()) {
+                                       switch (in.next()) {
+                                       case "enc":
+                                               for (CodingTask t : finished_encoding_task) {
+                                                       println_ok(""
+                                                                       + finished_encoding_task.lastIndexOf(t)
+                                                                       + "\t" + t.getFilePath().getFileName());
                                                }
-                                       } catch (Exception e) {
-                                               System.out.println("Index nicht gefunden");
+                                               break;
+                                       case "dec":
+                                               for (CodingTask t : finished_decoding_task) {
+                                                       println_ok(""
+                                                                       + finished_decoding_task.lastIndexOf(t)
+                                                                       + "\t" + t.getFilePath().getFileName());
+                                               }
+                                               break;
+
+                                       case "frag":
+                                               try {
+                                                       for (Entry<Integer, Path> e : finished_encoding_task
+                                                                       .get(Integer.parseInt(in.next()))
+                                                                       .getFragmentPaths().entrySet()) {
+                                                               String color = Files.exists(e.getValue()) ? ANSI_GREEN
+                                                                               : ANSI_RED;
+                                                               System.out.format(color + "\t %-5s %s %s\n"
+                                                                               + ANSI_RESET, e.getKey(), e.getValue()
+                                                                               .toString(),
+                                                                               (Files.exists(e.getValue()) ? "OK"
+                                                                                               : "Fehlt"));
+                                                               // println_std(++"\t"+e.getValue().toString());
+                                                       }
+                                               } catch (Exception e) {
+                                                       println_err("Index not found. Use 'ls enc' to show valid indices");
+                                               }
+                                               break;
+
+                                       case "splitter":
+                                       case "splitters":
+                                               print_splitter();
+                                               break;
+
+                                       case "codec":
+                                       case "codecs":
+                                                       print_codecs();
+                                               break;
                                        }
-                                       break;
-                                       
-                               case "src":
-                                       System.out.println("noch nicht implementiert");
-                                       break;
-                                       
-                                       
-                               case "splitter":
-                                       System.out.println("noch nicht implementiert");
-                                       break;
-                               
+
                                }
                                break;
 
                        case "meta":
-                               switch(in.next()){
-                               case "enc":
-                                       try {
-                                               for (Entry<String, Object> e : finished_encoding_task
-                                                               .get(Integer.parseInt(in.next())).getMetadata()
-                                                               .entrySet()) {
-                                                       System.out.format("\t %-25s %-25s %s\n", e.getKey(), e
-                                                                       .getValue().toString(), e.getValue().getClass()
-                                                                       .toString());
-                                                       // System.out.println(++"\t"+e.getValue().toString());
+                               if (in.hasNext()) {
+                                       switch (in.next()) {
+                                       case "enc":
+                                               try {
+                                                       for (Entry<String, Object> e : finished_encoding_task
+                                                                       .get(Integer.parseInt(in.next()))
+                                                                       .getMetadata().entrySet()) {
+                                                               println_ok(String.format("\t %-25s %-25s %s",
+                                                                               e.getKey(), e.getValue().toString(), e
+                                                                                               .getValue().getClass()
+                                                                                               .toString()));
+                                                               // println_std(++"\t"+e.getValue().toString());
+                                                       }
+                                               } catch (Exception e) {
+                                                       println_err("Index not found. Use 'ls enc' to show valid indices");
                                                }
-                                       } catch (Exception e) {
-                                               System.out.println("Index nicht gefunden");
-                                       }
-                                       break;
-                               
-                               case "dec":
-                                       try {
-                                               for (Entry<String, Object> e : finished_decoding_task
-                                                               .get(Integer.parseInt(in.next())).getMetadata()
-                                                               .entrySet()) {
-                                                       System.out.format("\t %-25s %s\n", e.getKey(), e
-                                                                       .getValue().toString());
-                                                       // System.out.println(++"\t"+e.getValue().toString());
+                                               break;
+
+                                       case "dec":
+                                               try {
+                                                       for (Entry<String, Object> e : finished_decoding_task
+                                                                       .get(Integer.parseInt(in.next()))
+                                                                       .getMetadata().entrySet()) {
+                                                               println_ok(String.format("\t %-25s %s",
+                                                                               e.getKey(), e.getValue().toString()));
+                                                               // println_std(++"\t"+e.getValue().toString());
+                                                       }
+                                               } catch (Exception e) {
+                                                       println_err("Index not found. Use 'ls dec' to show valid indices");
                                                }
-                                       } catch (Exception e) {
-                                               System.out.println("Index nicht gefunden");
+                                               break;
                                        }
-                                       break;
                                }
                                break;
 
@@ -458,66 +265,369 @@ public class Filesplitter implements SplitterCallback {
                                        try {
                                                Files.delete(path);
                                        } catch (Exception e) {
-                                               System.out.println("Konnte fragment nicht löschen "
+                                               println_err("unable to delete fragment: "
                                                                + e.getMessage());
 
                                        }
 
                                } catch (Exception e) {
-                                       System.out.println("Index nicht gefunden");
+                                       println_err("Index not found. Use 'ls frag <index> ' to show valid indices");
                                }
                                break;
 
                        case "dec":
                                try {
                                        int tasknr = Integer.parseInt(in.next());
-                                       CodingTask enctask = (CodingTask) finished_encoding_task
-                                                       .get(tasknr);
-                                       Path restorefile = restoreDir.resolve(""
-                                                       + System.currentTimeMillis()
-                                                       + enctask.getFilePath().getFileName());
-
-                                       Map<Integer, Path> fragmentPaths = enctask
-                                                       .getFragmentPaths();
-                                       for (int i = 0; i < fragmentPaths.size(); i++) {
-                                               Path path = fragmentPaths.get(i);
-                                               if (path == null || !Files.exists(path)) {
-                                                       fragmentPaths.put(i, null);
-                                               }
+                                       decode(restoreDir, tasknr);
+                               } catch (Exception e) {
+                                       // e.printStackTrace();
+                                       println_err("Index not found. Use 'ls enc' to show valid indices");
+                               }
 
+                               break;
+                       case "enc":
+                               int splitternr;
+                               Splitter splitter;
+                               try {
+                                       splitternr = in.nextInt();
+                                       splitter = splitters.get(splitternr);
+                               } catch (Exception e1) {
+                                       // TODO Auto-generated catch block
+                                       println_err("no valid Splitter-Infex. Use 'ls splitter' to show valid indices");
+                                       break;
+                               }
+                               String filename;
+                               Path srcfile = null;
+                               try {
+                                       filename = in.next();
+                                       srcfile = Paths.get(filename);
+                                       if (Files.notExists(srcfile, LinkOption.NOFOLLOW_LINKS)) {
+                                               in.close();
+                                               throw new Exception();
                                        }
-                                       DecodingTask dectask = new DecodingTask(fragmentPaths,
-                                                       restorefile, this, enctask.getMetadataAsDeepCopy());
-                                       for (Splitter spl : splitters) {
-                                               if (spl.getCurrentPlugin().getPluginDescription()
-                                                               .getPluginID() == (String) enctask
-                                                               .getMetadata("pluginid")
-                                                               && spl.getCurrentCodecDescription()
-                                                                               .getCodecID() == (String) enctask
-                                                                               .getMetadata("codecid")) {
-                                                       System.out.println("Auftrag angenommen..."
-                                                                       + restorefile);
-                                                       spl.decode(dectask);
-                                                       running_tasks.add(dectask);
-                                               }
-                                       }
+                               } catch (Exception e1) {
+                                       println_err("no valid Filename. Use 'enc <splitternr> <Filename>'");
+                                       break;
+                               }
+                               try {
+                                       encode(srcfile, splitter);
+                               } catch (Exception e1) {
+                                       // TODO Auto-generated catch block
+                                       println_err(e1.getMessage()
+                                                       + "\nEncoding failed. Use 'enc <splitternr> <Filename>'");
+                               }
+                               break;
 
+                       case "init":
+                               try {
+                                       int codecnr = Integer.parseInt(in.next());
+                                       configure_codec(codecnr);
                                } catch (Exception e) {
-                                       e.printStackTrace();
-                                       System.out.println("Index nicht gefunden");
+                                       println_err("Index not found. Use 'ls codec' to show valid indices");
                                }
                                break;
-                       case "enc":
-                               System.out.println("noch nicht implementiert");
+                       case "reset":
+                               try {
+                                       int codecnr = Integer.parseInt(in.next());
+                                       reset_codec(codecnr);
+                               } catch (Exception e) {
+                                       println_err("Index not found. Use 'ls codec' to show valid indices");
+                               }
+
                                break;
-                               
-                       
                        default:
                                printUsage();
                        }
+                       in.close();
+               }
+
+       }
+
+       public void decode(Path restoreDir, int tasknr) {
+               try {
+                       CodingTask enctask = (CodingTask) finished_encoding_task
+                                       .get(tasknr);
+                       Path restorefile = restoreDir.resolve(""
+                                       + System.currentTimeMillis()
+                                       + enctask.getFilePath().getFileName());
+
+                       Map<Integer, Path> fragmentPaths = enctask.getFragmentPaths();
+                       for (int i = 0; i < fragmentPaths.size(); i++) {
+                               Path path = fragmentPaths.get(i);
+                               if (path == null || !Files.exists(path)) {
+                                       fragmentPaths.put(i, null);
+                               }
+
+                       }
+                       DecodingTask dectask = new DecodingTask(fragmentPaths, restorefile,
+                                       this, enctask.getMetadataAsDeepCopy());
+                       for (Splitter spl : splitters) {
+                               if (spl.getCurrentPlugin().getPluginDescription().getPluginID() == (String) enctask
+                                               .getMetadata("pluginid")
+                                               && spl.getCurrentCodecDescription().getCodecID() == (String) enctask
+                                                               .getMetadata("codecid")) {
+                                       println_ok("Auftrag angenommen..." + restorefile);
+                                       spl.decode(dectask);
+                                       running_tasks.add(dectask);
+                               }
+                       }
+
+               } catch (Exception e) {
+                       // e.printStackTrace();
+                       println_err("Index not found. Use 'ls enc' to show valid indices");
+               }
+       }
+
+       public void print_splitter() {
+               for (Splitter splitter : splitters) {
+                       String pid = splitter.getCurrentPlugin().getPluginDescription()
+                                       .getPluginID();
+                       String cid = splitter.getCurrentCodecDescription().getCodecID();
+                       println_ok(splitters.indexOf(splitter) + "\t" + pid + "/" + cid
+                                       + "  \t(" + splitter.getTaskQueueLength()
+                                       + " active Tasks)");
+               }
+       }
+
+       public void encode(Path srcfile, Splitter splitter) {
+               println_ok("Encoding: "
+                               + srcfile
+                               + "  with "
+                               + splitter.getCurrentPlugin().getPluginDescription()
+                                               .getPluginID() + "/"
+                               + splitter.getCurrentCodecDescription().getCodecID());
+               try {
+
+                       Map<String, Object> metadata = new TreeMap<String, Object>();
+
+                       for (Entry<String, Object> e : splitter_metadata_map.get(splitter)
+                                       .entrySet()) {
+                               metadata.put(e.getKey(), e.getValue());
+                       }
+
+                       metadata.put("time_encoding_submitted", System.currentTimeMillis());
+
+                       // Hier wird codiert. Der Encodingtask
+                       EncodingTask task = new EncodingTask(srcfile,
+                                       Paths.get("splitDir"), this, metadata);
+                       splitter.encode(task);
+                       running_tasks.add(task);
+               } catch (InterruptedException | IOException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public void saveconfig() {
+               try {
+                       config.store();
+                       println_ok("Configuration saved");
+               } catch (IOException e1) {
+                       // TODO Auto-generated catch block
+                       e1.printStackTrace();
+               }
+       }
+
+       public void init_config() {
+               try {
+                       File configfile = new File(CONFIGFILE);
+                       if (!configfile.exists()) {
+                               configfile.createNewFile();
+                       }
+                       config = new Ini(configfile);
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               for (PluginDescription p : Splitter.getPluginDescriptions()) {
+                       for (CodecDescription c : p.getCodecDescriptions()) {
+                               String id = p.getPluginID() + "/" + c.getCodecID();
+                               codeclist.add(id);
+                               if (isInConfig(id)) {
+                                       init_codec(id);
+                               }
+                       }
+               }
+       }
+
+       private boolean isInConfig(String id) {
+               Section s = config.get(id);
+               if (s != null && s.containsKey("k") && s.containsKey("m")) {
+                       return true;
+               }
+               return false;
+       }
+
+       private void init_codec(String id) {
+               Section section;
+               section = config.get(id);
+
+               // Build codecparameter map
+               Map<String, Integer> codecparameter = new HashMap<>();
+               for (Entry<String, String> e : section.entrySet()) {
+                       try {
+                               codecparameter.put(e.getKey(), Integer.parseInt(e.getValue()));
+                       } catch (Exception ex) {
+                               // nothing
+                       }
+               }
 
+               // build Metadata Template. Try tu use Integer, if it fails use String
+               section = config.get(id + "_MetadataTemplate");
+               Map<String, Object> metadatatemplate = new HashMap<>();
+               if (section != null) {
+                       for (Entry<String, String> entry : section.entrySet()) {
+                               try {
+                                       metadatatemplate.put(entry.getKey(),
+                                                       Integer.parseInt(entry.getValue()));
+                               } catch (NumberFormatException ex) {
+                                       try {
+                                               metadatatemplate.put(entry.getKey(), entry.getValue());
+                                       } catch (Exception e2) {
+                                               // TODO: handle exception
+                                       }
+                               }
+                       }
                }
 
+               for (PluginDescription p : Splitter.getPluginDescriptions()) {
+                       for (CodecDescription c : p.getCodecDescriptions()) {
+                               if (id.equals(p.getPluginID() + "/" + c.getCodecID())) {
+                                       try {
+                                               Splitter splitter = new Splitter(p.getPluginID(),
+                                                               c.getCodecID(), codecparameter);
+                                               splitters.add(splitter);
+                                               splitter_metadata_map.put(splitter, metadatatemplate);
+                                               codeclist_configured.add(id);
+                                               if (codeclist_failed.contains(id)){
+                                                       codeclist_failed.remove(id);
+                                               }
+                                               println_ok("Splitter created from config: " + id);
+                                       } catch (Exception e) {
+                                               println_err("NO Splitter created for: " + id + "\n"
+                                                               + e.getMessage());
+                                               codeclist_failed.add(id);
+                                               if (codeclist_configured.contains(id)){
+                                                       codeclist_configured.remove(id);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       private void reset_codec(int i) {
+               String id = getCodecIDfromIndex(i);
+               if (id == null) {
+                       println_err("Codec " + i + " existiert nicht");
+                       print_codecs();
+                       return;
+               }
+               config.remove(config.get(id));
+               saveconfig();
+               if (codeclist_configured.contains(id)){
+                       codeclist_configured.remove(id);
+               }
+               if (codeclist_failed.contains(id)){
+                       codeclist_failed.remove(id);
+               }
+               for (Splitter splitter : splitters) {
+                       String pid = splitter.getCurrentPlugin().getPluginDescription()
+                                       .getPluginID();
+                       String cid = splitter.getCurrentCodecDescription().getCodecID();
+                       if (id.equals(pid + "/" + cid)) {
+                               splitters.remove(splitter);
+                               splitter_metadata_map.remove(splitter);
+                               splitter.stop();
+                       }
+               }
+       }
+
+       public void configure_codec(int i) {
+               String id = getCodecIDfromIndex(i);
+               if (id == null) {
+                       println_err("Codec " + i + " existiert nicht");
+                       print_codecs();
+                       return;
+               }
+
+               for (PluginDescription p : Splitter.getPluginDescriptions()) {
+                       for (CodecDescription c : p.getCodecDescriptions()) {
+                               if (id.equals(p.getPluginID() + "/" + c.getCodecID())) {
+                                       Section section = config.get(id);
+                                       if (section == null) {
+                                               section = config.add(id);
+                                       }
+                                       print_codecdescription(p, c);
+                                       println_std(id + " Configuration:");
+                                       for (Entry<String, Integer[]> entry : c
+                                                       .getCodecParameterMinMax().entrySet()) {
+                                               print_std(entry.getKey());
+                                               print_std("\tmin="+ c.getCodecParameterMinMax().get(entry.getKey())[0]);
+                                               print_std("\tmax="+ c.getCodecParameterMinMax().get(entry.getKey())[1]);
+                                               if (c.getCodecParameterDefaults().get(entry.getKey()) != null) {
+                                                       print_std("\tdefault="
+                                                                       + c.getCodecParameterDefaults().get(
+                                                                                       entry.getKey()));
+                                                       section.put(entry.getKey(), readCommandline("\t"+entry.getKey()+"=",true));
+                                               }
+                                               else {
+                                                       section.put(entry.getKey(), readCommandline("\t"+entry.getKey()+"=",false));
+                                               }
+                                       }
+                                       println_std("");
+
+                                       section = config.get(id + "_MetadataTemplate");
+                                       if (section == null) {
+                                               section = config.add(id + "_MetadataTemplate");
+                                       }
+                                       section.put("fragmentsize", "4096");
+                                       saveconfig();
+                                       init_codec(id);
+                               }
+                       }
+               }
+
+       }
+
+       public String getCodecIDfromIndex(int i) {
+               String id;
+               try {
+                       id = codeclist.get(i);
+               } catch (Exception e) {
+                       return null;
+               }
+               return id;
+       }
+
+       public void print_codecs() {
+               println_info("----available codecs----");
+               for (String c : codeclist) {
+                       if (codeclist_configured.contains(c)) {
+                               println_ok(String.format("%-6s%-45s configured",
+                                               codeclist.indexOf(c), c));
+                       } else if (codeclist_failed.contains(c)) {
+                               println_err(String.format("%-6s%-45s invalid configuration",
+                                               codeclist.indexOf(c), c));
+                       }
+                       else {
+                               println_info(String.format("%-6s%-45s not configured",
+                                               codeclist.indexOf(c), c));
+                       }
+               }
+               println_std("use 'init <nr>' to configure codecs and 'reset <n>' to delete configuration");
+       }
+
+       public void print_codecdescription(PluginDescription p, CodecDescription c) {
+               println_info("\t|---------------------------------------------\n\t|"
+                               + c.getCodecID() + "\t" + c.getCodecDescriptionText());
+               Map<String, Integer[]> codecParameterMinMax = c
+                               .getCodecParameterMinMax();
+               for (Entry<String, Integer[]> e : codecParameterMinMax.entrySet()) {
+                       println_info(String.format(
+                                       "\t|\t%15s\tmin:%15s\tmax:%15s\tdefault:%15s", e.getKey(),
+                                       e.getValue()[0], e.getValue()[1], c
+                                                       .getCodecParameterDefaults().get(e.getKey())));
+               }
        }
 
        private static List<Path> getFileList(Path path) {
@@ -553,26 +663,26 @@ public class Filesplitter implements SplitterCallback {
 
        // private static void initSplitter(Splitter splitter) {
        //
-       // System.out.println("Liste der Codecs:");
+       // println_std("Liste der Codecs:");
        // Collection<String> codecids = splitter.getCodecIDs();
        // Iterator<String> it = codecids.iterator();
        // while (it.hasNext()){
-       // System.out.println("- " + it.next().toString());
+       // println_std("- " + it.next().toString());
        // }
        // if (codecids.contains("jerasureparity")){
        // SplitterConfiguration config = new SplitterConfiguration();
        // config.setCodecID("jerasureparity");
        // splitter.setSplitterConfiguration(config);
        // }
-       // System.out.println();
+       // println_std();
        // }
 
        @Override
        public void codingFailed(CodingTask task, String reason) {
                synchronized (task) { // damit die Ausgabe nicht verwürfelt wird
                        running_tasks.remove(task);
-                       System.err.println("Coding Failed: "
-                                       + task.getFilePath().toString() + "  Reason:" + reason);
+                       println_err("Coding Failed: " + task.getFilePath().toString()
+                                       + "  Reason:" + reason);
                }
 
        }
@@ -592,29 +702,57 @@ public class Filesplitter implements SplitterCallback {
                                                - (long) task.getMetadata("time_decode_start");
                        }
 
-                       System.err.println("CodingTask "
-                                       + finished_encoding_task.indexOf(task)
-                                       + " OK: " + task.getFilePath().toString()
-                                       + "  Codec: " + task.getMetadata("pluginid") + "/"
+                       println_ok("CodingTask " + finished_encoding_task.indexOf(task)
+                                       + " OK: " + task.getFilePath().toString() + "  Codec: "
+                                       + task.getMetadata("pluginid") + "/"
                                        + task.getMetadata("codecid") + "  T(ms):" + duration);
                }
        }
 
        public void printUsage() {
-               System.out.println("Bedienung:"
-                               //+ "\nls splitter\tlistet alle initialisierten Splitter auf"
-                               //+ "\nls src\t\tlistet alle Dateien in scrDir auf"
-                               + "\nls enc\t\tlistet alle fertig encodierten Tasks auf"
-                               + "\nls dec\t\tlistet alle fertig decodierten Tasks auf"
-                               + "\nls frag <nr>\tlistet die Fragmentdateien zu Encoding-Task <nr> auf"
-                               + "\nrm <nr> <frac_nr>\tlöscht aus Encoding-Task <nr> die Fragmentdatei <frac_nr>"
-                               + "\ndec <nr>\twiederherstellen der Originaldatei aus Encoding-Task <nr> in das Verzeichnis restoreDir"
-                               //+ "\nenc <scr_nr> <splitter_nr>\tencodieren von Datei <scr_nr> mit Splitter <split-ter_nr>"
-                               + "\nmeta enc <nr>\tgibt metadaten zu encodingtask <nr> aus"
-                               + "\nmeta dec <nr>\tgibt metadaten zu decodingtask <nr> aus"
-                               + "\nq, quit oder exit\tbeenden das Programm"
-                               //+" \nh oder help\tzeigt die Hilfe an"
-                               + "");
+               println_std("Bedienung:");
+               println_std("init");
+               println_std("reset");
+               println_std( "ls splitter\tlistet alle initialisierten Splitter auf");
+               println_std( "ls codec\t\tlistet alle codecs auf");
+               println_std("ls enc\t\tlistet alle fertig encodierten Tasks auf");
+               println_std("ls dec\t\tlistet alle fertig decodierten Tasks auf");
+               println_std("ls frag <nr>\tlistet die Fragmentdateien zu Encoding-Task <nr> auf");
+               println_std("rm <nr> <frac_nr>\tlöscht aus Encoding-Task <nr> die Fragmentdatei <frac_nr>");
+               println_std("dec <nr>\twiederherstellen der Originaldatei aus Encoding-Task <nr> in das Verzeichnis restoreDir");
+               println_std("enc <splitternr> <filename>\tencodieren files with a splitter");
+               println_std("meta enc <nr>\tgibt metadaten zu encodingtask <nr> aus");
+               println_std("meta dec <nr>\tgibt metadaten zu decodingtask <nr> aus");
+               println_std("q, quit oder exit\tbeenden das Programm");
+               // +" \nh oder help\tzeigt die Hilfe an"
+               println_std("");
+       }
+
+       public void println_std(String str) {
+               print_std(str + "\n");
        }
 
+       public void print_std(String str) {
+               System.out.print(ANSI_RESET + str + ANSI_RESET);
+       }
+
+       public void println_err(String str) {
+               System.out.println(ANSI_RED + str + ANSI_RESET);
+       }
+
+       public void print_ok(String str) {
+               System.out.print(ANSI_GREEN + str + ANSI_RESET);
+       }
+
+       public void println_ok(String str) {
+               print_ok(str + "\n");
+       }
+
+       public void println_dbg(String str) {
+               System.out.println(ANSI_RESET + str + ANSI_RESET);
+       }
+
+       public void println_info(String str) {
+               System.out.println(ANSI_BOLD + ANSI_YELLOW + str + ANSI_RESET);
+       }
 }
diff --git a/Splitter-ng-filesplitter/src/Test.java b/Splitter-ng-filesplitter/src/Test.java
new file mode 100644 (file)
index 0000000..fc59a1d
--- /dev/null
@@ -0,0 +1,43 @@
+import java.io.File;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import org.ini4j.Ini;
+import org.ini4j.Profile.Section;
+
+
+public class Test {
+       public static Ini config;
+       public static String CONFIGFILE ="filesplitter.ini";
+
+       public static void main(String[] args) {
+               // TODO Auto-generated method stub
+               Test t=new Test();
+               try {
+                       File configfile = new File(CONFIGFILE);
+                       if (!configfile.exists()){
+                               configfile.createNewFile();
+                       }
+                       config = new Ini(configfile);
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               t.run();
+       }
+
+       public void run(){
+               String id = "Test";
+               Section s = config.get(id+"_MetadataTemplate");
+               Map<String, Object> metadatatemplate = new TreeMap<String, Object>();
+               
+               for (Entry<String, String> e : s.entrySet()){
+                       try{
+                               metadatatemplate.put(e.getKey(), Integer.parseInt(e.getValue()));
+                       } catch (Exception e1) {
+                               e1.printStackTrace();
+                       }
+               }
+       }
+}