Index: AE/installer2/src/net/oni2/aeinstaller/backend/mods/EBSLInstallType.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/mods/EBSLInstallType.java	(revision 600)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/mods/EBSLInstallType.java	(revision 600)
@@ -0,0 +1,19 @@
+package net.oni2.aeinstaller.backend.mods;
+
+/**
+ * @author Christian Illy
+ */
+public enum EBSLInstallType {
+	/**
+	 * No BSL files
+	 */
+	NONE,
+	/**
+	 * Normal BSL install mode
+	 */
+	NORMAL,
+	/**
+	 * BSL addon install mode
+	 */
+	ADDON
+}
Index: AE/installer2/src/net/oni2/aeinstaller/backend/mods/ECompatiblePlatform.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/mods/ECompatiblePlatform.java	(revision 600)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/mods/ECompatiblePlatform.java	(revision 600)
@@ -0,0 +1,19 @@
+package net.oni2.aeinstaller.backend.mods;
+
+/**
+ * @author Christian Illy
+ */
+public enum ECompatiblePlatform {
+	/**
+	 * Only for Win
+	 */
+	WIN,
+	/**
+	 * Only for MacOS
+	 */
+	MACOS,
+	/**
+	 * Usable with both platforms
+	 */
+	BOTH
+}
Index: AE/installer2/src/net/oni2/aeinstaller/backend/mods/Mod.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/mods/Mod.java	(revision 598)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/mods/Mod.java	(revision 600)
@@ -1,5 +1,19 @@
 package net.oni2.aeinstaller.backend.mods;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.HashSet;
+
+import net.oni2.aeinstaller.backend.Paths;
+import net.oni2.aeinstaller.backend.Settings;
+import net.oni2.aeinstaller.backend.Settings.Platform;
+import net.oni2.aeinstaller.backend.depot.DepotManager;
+import net.oni2.aeinstaller.backend.depot.model.NodeMod;
+import net.oni2.aeinstaller.backend.depot.model.TaxonomyTerm;
 
 /**
@@ -7,33 +21,282 @@
  */
 public class Mod implements Comparable<Mod> {
-	private double aeVersion;
-	private int node;
-	private int packageNumber;
-
-	public double getAEVersion() {
-		return aeVersion;
-	}
-
+	// TODO: Dependencies/Conflicts
+	
+	private String name = "";
+	private int packageNumber = 0;
+
+	private HashSet<Type> types = new HashSet<Type>();
+	private ECompatiblePlatform platform = null;
+	private String version = "";
+	private String creator = "";
+	private EBSLInstallType bslInstallType = null;
+	private String description = "";
+	private double aeVersion = 0;
+	private int zipSize = 0;
+	private NodeMod node = null;
+	private net.oni2.aeinstaller.backend.depot.model.File file = null;
+
+	private long localTimestamp = 0;
+
+	/**
+	 * Create a new Mod entry from a given Mod-Node
+	 * 
+	 * @param nm
+	 *            Mod-Node
+	 */
+	public Mod(NodeMod nm) {
+		node = nm;
+		name = nm.getTitle();
+		packageNumber = nm.getPackageNumber();
+		for (TaxonomyTerm tt : nm.getTypes()) {
+			Type t = ModManager.getInstance().getTypeByName(tt.getName());
+			types.add(t);
+			t.addEntry(this);
+		}
+		platform = nm.getPlatform();
+		version = nm.getVersion();
+		creator = nm.getCreator();
+		if (nm.getBody() != null)
+			description = nm.getBody().getSafe_value();
+		file = DepotManager.getInstance().getFile(
+				nm.getUploads().firstElement().getFid());
+		zipSize = file.getFilesize();
+
+		if (isLocalAvailable())
+			updateLocalData();
+	}
+
+	/**
+	 * Update information for local package existence
+	 */
+	public void updateLocalData() {
+		File config = new File(getLocalPath(), "Mod_Info.cfg");
+		File timestamp = new File(getLocalPath(), "aei.cfg");
+		if (config.exists()) {
+			try {
+				FileInputStream fstream = new FileInputStream(config);
+				InputStreamReader isr = new InputStreamReader(fstream);
+				BufferedReader br = new BufferedReader(isr);
+				String strLine;
+				while ((strLine = br.readLine()) != null) {
+					if (strLine.indexOf("->") < 1)
+						continue;
+					if (strLine.indexOf("//") >= 0)
+						strLine = strLine.substring(0, strLine.indexOf("//"));
+					String[] split = strLine.split("->", 2);
+					String sName = split[0].trim();
+					String sVal = split[1].trim();
+					if (sName.equalsIgnoreCase("AEInstallVersion")) {
+						aeVersion = Double.parseDouble(sVal);
+					} else if (sName.equalsIgnoreCase("NameOfMod")) {
+						if (node == null)
+							name = sVal;
+					} else if (sName.equalsIgnoreCase("Creator")) {
+						if (node == null)
+							creator = sVal;
+					} else if (sName.equalsIgnoreCase("HasBsl")) {
+						if (sVal.equalsIgnoreCase("addon"))
+							bslInstallType = EBSLInstallType.ADDON;
+						else if (sVal.equalsIgnoreCase("yes"))
+							bslInstallType = EBSLInstallType.NORMAL;
+						else
+							bslInstallType = EBSLInstallType.NONE;
+					} else if (sName.equalsIgnoreCase("ModVersion")) {
+						if (node == null)
+							version = sVal;
+					} else if (sName.equalsIgnoreCase("Readme")) {
+						if (node == null)
+							description = sVal.replaceAll("\\\\n", "<br>");
+					}
+				}
+				isr.close();
+			} catch (FileNotFoundException e) {
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		} else {
+			System.err.println("No config found for mod folder: "
+					+ getLocalPath().getPath());
+		}
+		if (timestamp.exists()) {
+			try {
+				FileInputStream fstream = new FileInputStream(timestamp);
+				InputStreamReader isr = new InputStreamReader(fstream);
+				BufferedReader br = new BufferedReader(isr);
+				String ts = br.readLine();
+				localTimestamp = Long.parseLong(ts);
+				isr.close();
+			} catch (FileNotFoundException e) {
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	/**
+	 * Create a new Mod entry from the given local mod folder
+	 * 
+	 * @param folder
+	 *            Mod folder with Mod_Info.cfg
+	 */
+	public Mod(File folder) {
+		packageNumber = Integer.parseInt(folder.getName().substring(0, 5));
+		updateLocalData();
+
+		Type t = ModManager.getInstance().getTypeByName("-Local-");
+		types.add(t);
+		t.addEntry(this);
+
+		platform = ECompatiblePlatform.BOTH;
+	}
+
+	/**
+	 * @return has separate paths for win/mac/common or not
+	 */
 	public boolean hasSeparatePlatformDirs() {
 		return aeVersion >= 2;
 	}
 
+	/**
+	 * @return Path to local mod folder
+	 */
 	public File getLocalPath() {
-		// TODO
-		return null;
-	}
-	
-	public boolean newerAvailable() {
-		//TODO
-		return false;
-	}
-	
-	public boolean localAvailable() {
-		//TODO
-		return false;
-	}
-	
+		final String folderStart = String.format("%05d", packageNumber);
+
+		if (Paths.getModsPath().exists()) {
+			for (File f : Paths.getModsPath().listFiles(new FilenameFilter() {
+				@Override
+				public boolean accept(File d, String fn) {
+					return fn.startsWith(folderStart);
+				}
+			})) {
+				return f;
+			}
+		}
+
+		return new File(Paths.getModsPath(), folderStart);
+	}
+
+	/**
+	 * @return Is there a newer version on the depot?
+	 */
+	public boolean isNewerAvailable() {
+		if (node != null)
+			return node.getUploads().firstElement().getTimestamp() > localTimestamp;
+		else
+			return false;
+	}
+
+	/**
+	 * @return Mod exists within mods folder
+	 */
+	public boolean isLocalAvailable() {
+		return getLocalPath().exists();
+	}
+
+	/**
+	 * @return Name of mod
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @return the package number
+	 */
 	public int getPackageNumber() {
 		return packageNumber;
+	}
+
+	/**
+	 * @return Types of mod
+	 */
+	public HashSet<Type> getTypes() {
+		return types;
+	}
+
+	/**
+	 * @return Compatible platforms
+	 */
+	public ECompatiblePlatform getPlatform() {
+		return platform;
+	}
+
+	/**
+	 * @return Version of mod
+	 */
+	public String getVersion() {
+		return version;
+	}
+
+	/**
+	 * @return Creator of mod
+	 */
+	public String getCreator() {
+		return creator;
+	}
+
+	/**
+	 * @return Installation type of BSL files
+	 */
+	public EBSLInstallType getBSLInstallType() {
+		return bslInstallType;
+	}
+
+	/**
+	 * @return Description of mod
+	 */
+	public String getDescription() {
+		return description;
+	}
+
+	/**
+	 * @return Size of Zip file on Depot
+	 */
+	public int getZipSize() {
+		return zipSize;
+	}
+
+	/**
+	 * @return Depot Mod-Node
+	 */
+	public NodeMod getNode() {
+		return node;
+	}
+
+	/**
+	 * @return Is a mod that is always installed?
+	 */
+	public boolean isDefaultMod() {
+		return packageNumber < 10000;
+	}
+
+	/**
+	 * @return Get the depot file entry
+	 */
+	public net.oni2.aeinstaller.backend.depot.model.File getFile() {
+		return file;
+	}
+
+	@Override
+	public String toString() {
+		return name;
+	}
+
+	/**
+	 * @return Is this mod valid on the running platform?
+	 */
+	public boolean validOnPlatform() {
+		ECompatiblePlatform plat = platform;
+		switch (plat) {
+			case BOTH:
+				return true;
+			case MACOS:
+				return (Settings.getPlatform() == Platform.MACOS);
+			case WIN:
+				return (Settings.getPlatform() == Platform.WIN)
+						|| (Settings.getPlatform() == Platform.LINUX);
+		}
+		return false;
 	}
 
Index: AE/installer2/src/net/oni2/aeinstaller/backend/mods/ModManager.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/mods/ModManager.java	(revision 600)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/mods/ModManager.java	(revision 600)
@@ -0,0 +1,112 @@
+package net.oni2.aeinstaller.backend.mods;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Vector;
+
+import net.oni2.aeinstaller.backend.Paths;
+import net.oni2.aeinstaller.backend.depot.DepotManager;
+import net.oni2.aeinstaller.backend.depot.model.NodeMod;
+import net.oni2.aeinstaller.backend.depot.model.TaxonomyTerm;
+
+/**
+ * @author Christian Illy
+ */
+public class ModManager {
+	// Download mods
+	// Update mods
+
+	private static ModManager instance = new ModManager();
+
+	private HashMap<String, Type> types = new HashMap<String, Type>();
+	private HashMap<Integer, Mod> mods = new HashMap<Integer, Mod>();
+
+	/**
+	 * First initialization of ModManager
+	 */
+	public void init() {
+		types = new HashMap<String, Type>();
+		mods = new HashMap<Integer, Mod>();
+
+		types.put("-Local-", new Type("-Local-", null));
+
+		for (TaxonomyTerm tt : DepotManager.getInstance()
+				.getTaxonomyTermsByVocabulary(
+						DepotManager.getInstance().getVocabIdType())) {
+			types.put(tt.getName(), new Type(tt.getName(), tt));
+		}
+
+		HashMap<Integer, Mod> modFolders = new HashMap<Integer, Mod>();
+		if (Paths.getModsPath().exists()) {
+			for (File f : Paths.getModsPath().listFiles(new FileFilter() {
+				@Override
+				public boolean accept(File pathname) {
+					return pathname.isDirectory();
+				}
+			})) {
+				Mod m = new Mod(f);
+				modFolders.put(m.getPackageNumber(), m);
+			}
+		}
+
+		for (NodeMod nm : DepotManager.getInstance().getModPackageNodes()) {
+			if (nm.getUploads().size() == 1) {
+				Mod m = new Mod(nm);
+				mods.put(m.getPackageNumber(), m);
+				modFolders.remove(m.getPackageNumber());
+			}
+		}
+
+		for (Mod m : modFolders.values()) {
+			mods.put(m.getPackageNumber(), m);
+		}
+	}
+
+	public void refreshLocalMods() {
+		// TODO: evtl nur private e.g. als listener für downloads?
+	}
+
+	/**
+	 * @return Singleton instance
+	 */
+	public static ModManager getInstance() {
+		return instance;
+	}
+
+	Type getTypeByName(String name) {
+		return types.get(name);
+	}
+
+	/**
+	 * @return Collection of types which do have mods associated
+	 */
+	public Collection<Type> getTypesWithContent() {
+		Vector<Type> res = new Vector<Type>();
+		for (Type t : types.values()) {
+			if (t.getEntries().size() > 0)
+				res.add(t);
+		}
+		return res;
+	}
+
+	/**
+	 * @return Collection of mods
+	 */
+	public Collection<Mod> getMods() {
+		return mods.values();
+	}
+
+	/**
+	 * @return Mods which are always installed
+	 */
+	public Collection<Mod> getDefaultMods() {
+		Vector<Mod> res = new Vector<Mod>();
+		for (Mod m : mods.values()) {
+			if (m.isDefaultMod())
+				res.add(m);
+		}
+		return res;
+	}
+}
Index: AE/installer2/src/net/oni2/aeinstaller/backend/mods/Type.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/mods/Type.java	(revision 600)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/mods/Type.java	(revision 600)
@@ -0,0 +1,51 @@
+package net.oni2.aeinstaller.backend.mods;
+
+import java.util.HashSet;
+
+import net.oni2.aeinstaller.backend.depot.model.TaxonomyTerm;
+
+/**
+ * @author Christian Illy
+ */
+public class Type {
+	String name;
+	TaxonomyTerm depotTerm;
+
+	HashSet<Mod> entries = new HashSet<Mod>();
+
+	/**
+	 * Create a new local type declaration
+	 * 
+	 * @param name
+	 *            Name of type
+	 * @param tt
+	 *            Optional TaxTerm link
+	 */
+	public Type(String name, TaxonomyTerm tt) {
+		this.name = name;
+		this.depotTerm = tt;
+	}
+
+	void addEntry(Mod m) {
+		entries.add(m);
+	}
+
+	/**
+	 * @return Name of type
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @return Entries for type
+	 */
+	public HashSet<Mod> getEntries() {
+		return entries;
+	}
+
+	@Override
+	public String toString() {
+		return String.format("%s (%d)", name, entries.size());
+	}
+}
