Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/HeuristicLab.DeploymentService.AdminClient.csproj
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/HeuristicLab.DeploymentService.AdminClient.csproj	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/HeuristicLab.DeploymentService.AdminClient.csproj	(revision 2804)
@@ -124,5 +124,4 @@
     <None Include="Service References\AdminService\service.xsd" />
     <None Include="Service References\AdminService\service1.xsd" />
-    <None Include="Service References\AdminService\System.xsd" />
   </ItemGroup>
   <ItemGroup>
@@ -152,5 +151,4 @@
     <None Include="Properties\DataSources\HeuristicLab.PluginInfrastructure.PluginUpdateService.PluginDescription.datasource" />
     <None Include="Properties\DataSources\HeuristicLab.PluginInfrastructure.PluginUpdateService.ProductDescription.datasource" />
-    <None Include="Service References\AdminService\HeuristicLab.Services.Deployment.DataAccess.xsd" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/PluginListView.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/PluginListView.cs	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/PluginListView.cs	(revision 2804)
@@ -44,11 +44,7 @@
 
     private HeuristicLab.PluginInfrastructure.PluginUpdateService.PluginDescription MakePluginDescription(IPluginDescription plugin) {
-      var desc = new HeuristicLab.PluginInfrastructure.PluginUpdateService.PluginDescription();
-      desc.Name = plugin.Name;
-      desc.Version = plugin.Version;
-      foreach (var dep in plugin.Dependencies) {
-        // TODO implement
-      }
-      return desc;
+      var dependencies = from dep in plugin.Dependencies
+                         select MakePluginDescription(dep);
+      return new HeuristicLab.PluginInfrastructure.PluginUpdateService.PluginDescription(plugin.Name, plugin.Version, dependencies);
     }
 
@@ -99,14 +95,31 @@
     private void listView_SelectedIndexChanged(object sender, EventArgs e) {
       if (listView.SelectedItems.Count > 0) {
-        var plugin = (IPluginDescription)listView.SelectedItems[0].Tag;
-        StringBuilder strBuilder = new StringBuilder();
+        if (listView.SelectedItems[0].Tag is IPluginDescription) {
+          var plugin = (IPluginDescription)listView.SelectedItems[0].Tag;
+          StringBuilder strBuilder = new StringBuilder();
 
-        strBuilder.Append("Name: ").AppendLine(plugin.Name);
-        strBuilder.Append("Version: ").AppendLine(plugin.Version.ToString());
-        strBuilder.AppendLine("Files:");
-        foreach (var file in plugin.Files) {
-          strBuilder.Append(file.Name + " " + file.Type);
+          strBuilder.Append("Name: ").AppendLine(plugin.Name);
+          strBuilder.Append("Version: ").AppendLine(plugin.Version.ToString());
+          strBuilder.AppendLine("Files:");
+          foreach (var file in plugin.Files) {
+            strBuilder.Append(file.Name + " " + file.Type);
+          }
+          strBuilder.AppendLine("Dependencies:");
+          foreach (var dep in plugin.Dependencies) {
+            strBuilder.Append(dep.Name + " " + dep.Version);
+          }
+          detailsTextBox.Text = strBuilder.ToString();
+        } else if (listView.SelectedItems[0].Tag is HeuristicLab.PluginInfrastructure.PluginUpdateService.PluginDescription) {
+          var plugin = (HeuristicLab.PluginInfrastructure.PluginUpdateService.PluginDescription)listView.SelectedItems[0].Tag;
+          StringBuilder strBuilder = new StringBuilder();
+
+          strBuilder.Append("Name: ").AppendLine(plugin.Name);
+          strBuilder.Append("Version: ").AppendLine(plugin.Version.ToString());
+          strBuilder.AppendLine("Dependencies:");
+          foreach (var dep in plugin.Dependencies) {
+            strBuilder.Append(dep.Name + " " + dep.Version);
+          }
+          detailsTextBox.Text = strBuilder.ToString();
         }
-        detailsTextBox.Text = strBuilder.ToString();
       } else {
         detailsTextBox.Text = string.Empty;
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/ProductEditor.Designer.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/ProductEditor.Designer.cs	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/ProductEditor.Designer.cs	(revision 2804)
@@ -60,5 +60,4 @@
       this.pluginsList.Location = new System.Drawing.Point(6, 85);
       this.pluginsList.Name = "pluginsList";
-      this.pluginsList.SelectionMode = System.Windows.Forms.SelectionMode.None;
       this.pluginsList.Size = new System.Drawing.Size(347, 289);
       this.pluginsList.TabIndex = 1;
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/ProductEditor.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/ProductEditor.cs	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/ProductEditor.cs	(revision 2804)
@@ -72,4 +72,5 @@
 
     private void productsListBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (productsListBox.SelectedItems.Count == 0) return;
       UpdateService.ProductDescription activeProduct = (UpdateService.ProductDescription)((ListViewItem)productsListBox.SelectedItem).Tag;
       UpdateProductDetails(activeProduct);
@@ -105,7 +106,5 @@
 
     private void newProductButton_Click(object sender, EventArgs e) {
-      var newProduct = new UpdateService.ProductDescription();
-      newProduct.Name = "New product";
-      newProduct.Version = new Version("0.0.0.0");
+      var newProduct = new UpdateService.ProductDescription("New product", new Version("0.0.0.0"));
       ListViewItem item = CreateListViewItem(newProduct);
       productsListBox.Items.Add(item);
@@ -116,4 +115,5 @@
       ListViewItem item = new ListViewItem();
       item.Text = productDescription.Name + " " + productDescription.Version;
+      item.Name = productDescription.Name + " " + productDescription.Version;
       item.Tag = productDescription;
       return item;
@@ -133,4 +133,5 @@
         activeProduct.Name = nameTextBox.Text;
         activeItem.Text = activeProduct.Name + " " + activeProduct.Version;
+        activeItem.Name = activeProduct.Name + " " + activeProduct.Version;
         errorProvider.SetError(nameTextBox, string.Empty);
       }
@@ -143,4 +144,5 @@
         activeProduct.Version = new Version(versionTextBox.Text);
         activeItem.Text = activeProduct.Name + " " + activeProduct.Version;
+        activeItem.Name = activeProduct.Name + " " + activeProduct.Version;
         errorProvider.SetError(versionTextBox, string.Empty);
       }
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Properties/AssemblyInfo.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Properties/AssemblyInfo.cs	(revision 2804)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Properties/AssemblyInfo.cs	(revision 2804)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.DeploymentService.AdminClient")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2010 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("863021a4-3cde-48be-8af6-dac1077f5fb5")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.0.9999")]
Index: anches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/HeuristicLab.Services.Deployment.DataAccess.xsd
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/HeuristicLab.Services.Deployment.DataAccess.xsd	(revision 2803)
+++ 	(revision )
@@ -1,26 +1,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" xmlns:xs="http://www.w3.org/2001/XMLSchema">
-  <xs:import namespace="http://schemas.datacontract.org/2004/07/System" />
-  <xs:complexType name="ProductDescription">
-    <xs:sequence>
-      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
-      <xs:element minOccurs="0" name="Plugins" nillable="true" type="tns:ArrayOfPluginDescription" />
-      <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/System" minOccurs="0" name="Version" nillable="true" type="q1:Version" />
-    </xs:sequence>
-  </xs:complexType>
-  <xs:element name="ProductDescription" nillable="true" type="tns:ProductDescription" />
-  <xs:complexType name="ArrayOfPluginDescription">
-    <xs:sequence>
-      <xs:element minOccurs="0" maxOccurs="unbounded" name="PluginDescription" nillable="true" type="tns:PluginDescription" />
-    </xs:sequence>
-  </xs:complexType>
-  <xs:element name="ArrayOfPluginDescription" nillable="true" type="tns:ArrayOfPluginDescription" />
-  <xs:complexType name="PluginDescription">
-    <xs:sequence>
-      <xs:element minOccurs="0" name="Dependencies" nillable="true" type="tns:ArrayOfPluginDescription" />
-      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
-      <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/System" minOccurs="0" name="Version" nillable="true" type="q2:Version" />
-    </xs:sequence>
-  </xs:complexType>
-  <xs:element name="PluginDescription" nillable="true" type="tns:PluginDescription" />
-</xs:schema>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/Reference.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/Reference.cs	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/Reference.cs	(revision 2804)
@@ -17,8 +17,8 @@
         
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAdmin/DeployProduct", ReplyAction="http://tempuri.org/IAdmin/DeployProductResponse")]
-        void DeployProduct(HeuristicLab.PluginInfrastructure.PluginUpdateService.ProductDescription product);
+        void DeployProduct(object product);
         
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAdmin/DeployPlugin", ReplyAction="http://tempuri.org/IAdmin/DeployPluginResponse")]
-        void DeployPlugin(HeuristicLab.PluginInfrastructure.PluginUpdateService.PluginDescription plugin, byte[] zipFile);
+        void DeployPlugin(object plugin, byte[] zipFile);
     }
     
@@ -50,9 +50,9 @@
         }
         
-        public void DeployProduct(HeuristicLab.PluginInfrastructure.PluginUpdateService.ProductDescription product) {
+        public void DeployProduct(object product) {
             base.Channel.DeployProduct(product);
         }
         
-        public void DeployPlugin(HeuristicLab.PluginInfrastructure.PluginUpdateService.PluginDescription plugin, byte[] zipFile) {
+        public void DeployPlugin(object plugin, byte[] zipFile) {
             base.Channel.DeployPlugin(plugin, zipFile);
         }
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/Reference.svcmap
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/Reference.svcmap	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/Reference.svcmap	(revision 2804)
@@ -24,6 +24,4 @@
     <MetadataFile FileName="service.xsd" MetadataType="Schema" ID="6774d012-d9eb-4ea5-8feb-928871eb8e1d" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Admin/mex" />
     <MetadataFile FileName="service1.xsd" MetadataType="Schema" ID="c727df39-bb61-4c79-bd42-a7b6e36d66bd" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Admin/mex" />
-    <MetadataFile FileName="HeuristicLab.Services.Deployment.DataAccess.xsd" MetadataType="Schema" ID="cb679c8e-6b04-4e08-ba43-5ebdacd52878" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Admin/mex" />
-    <MetadataFile FileName="System.xsd" MetadataType="Schema" ID="ef187830-0168-465c-a3b8-5535665e4bb2" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Admin/mex" />
   </Metadata>
   <Extensions>
Index: anches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/System.xsd
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/System.xsd	(revision 2803)
+++ 	(revision )
@@ -1,12 +1,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/System" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/System" xmlns:xs="http://www.w3.org/2001/XMLSchema">
-  <xs:complexType name="Version">
-    <xs:sequence>
-      <xs:element name="_Build" type="xs:int" />
-      <xs:element name="_Major" type="xs:int" />
-      <xs:element name="_Minor" type="xs:int" />
-      <xs:element name="_Revision" type="xs:int" />
-    </xs:sequence>
-  </xs:complexType>
-  <xs:element name="Version" nillable="true" type="tns:Version" />
-</xs:schema>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/service.wsdl
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/service.wsdl	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/service.wsdl	(revision 2804)
@@ -187,6 +187,4 @@
       <xsd:import namespace="http://tempuri.org/" />
       <xsd:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
-      <xsd:import namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" />
-      <xsd:import namespace="http://schemas.datacontract.org/2004/07/System" />
     </xsd:schema>
   </wsdl:types>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/service.xsd
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/service.xsd	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.DeploymentService.AdminClient/Service References/AdminService/service.xsd	(revision 2804)
@@ -1,9 +1,8 @@
 ﻿<?xml version="1.0" encoding="utf-8"?>
 <xs:schema xmlns:tns="http://tempuri.org/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
-  <xs:import namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" />
   <xs:element name="DeployProduct">
     <xs:complexType>
       <xs:sequence>
-        <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" minOccurs="0" name="product" nillable="true" type="q1:ProductDescription" />
+        <xs:element minOccurs="0" name="product" nillable="true" type="xs:anyType" />
       </xs:sequence>
     </xs:complexType>
@@ -17,5 +16,5 @@
     <xs:complexType>
       <xs:sequence>
-        <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" minOccurs="0" name="plugin" nillable="true" type="q2:PluginDescription" />
+        <xs:element minOccurs="0" name="plugin" nillable="true" type="xs:anyType" />
         <xs:element minOccurs="0" name="zipFile" nillable="true" type="xs:base64Binary" />
       </xs:sequence>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.DataAccess/HeuristicLab.Services.Deployment.DataAccess.csproj
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.DataAccess/HeuristicLab.Services.Deployment.DataAccess.csproj	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.DataAccess/HeuristicLab.Services.Deployment.DataAccess.csproj	(revision 2804)
@@ -53,6 +53,4 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="PluginDescription.cs" />
-    <Compile Include="PluginStore.cs" />
     <Compile Include="PluginStoreClasses.cs">
       <DependentUpon>PluginStoreClasses.dbml</DependentUpon>
@@ -63,5 +61,4 @@
       <DependentUpon>PluginStoreClasses.dbml</DependentUpon>
     </Compile>
-    <Compile Include="ProductDescription.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\Settings.Designer.cs">
Index: anches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.DataAccess/PluginDescription.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.DataAccess/PluginDescription.cs	(revision 2803)
+++ 	(revision )
@@ -1,40 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Runtime.Serialization;
-
-namespace HeuristicLab.Services.Deployment.DataAccess {
-  [DataContract(Name = "PluginDescription")]
-  public class PluginDescription {
-
-    [DataMember(Name = "Name")]
-    private string name;
-    public string Name {
-      get { return name; }
-    }
-
-    [DataMember(Name = "Version")]
-    private Version version;
-    public Version Version {
-      get { return version; }
-    }
-
-
-    [DataMember(Name = "Dependencies")]
-    private List<PluginDescription> dependencies;
-    public List<PluginDescription> Dependencies {
-      get { return dependencies; }
-    }
-
-    public PluginDescription(string name, Version version, IEnumerable<PluginDescription> dependencies) {
-      this.name = name;
-      this.version = version;
-      this.dependencies = new List<PluginDescription>(dependencies); //.AsReadOnly();
-    }
-
-    public PluginDescription(string name, Version version)
-      : this(name, version, Enumerable.Empty<PluginDescription>()) {
-    }
-  }
-}
Index: anches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.DataAccess/PluginStore.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.DataAccess/PluginStore.cs	(revision 2803)
+++ 	(revision )
@@ -1,230 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Data.Common;
-using System.Transactions;
-using System.Data.SqlClient;
-
-namespace HeuristicLab.Services.Deployment.DataAccess {
-  public class PluginStore {
-
-    public PluginStore() {
-    }
-
-    #region context creating members
-    public IEnumerable<ProductDescription> Products {
-      get {
-        using (var ctx = new PluginStoreClassesDataContext()) {
-          return (from p in ctx.Products
-                  let plugins = from pair in ctx.ProductPlugins
-                                from plugin in ctx.Plugins
-                                where pair.ProductId == p.Id
-                                where plugin.Id == pair.PluginId
-                                select plugin
-                  select MakeProductDescription(ctx, p, plugins)).ToList();
-        }
-      }
-    }
-
-    public IEnumerable<PluginDescription> Plugins {
-      get {
-        using (var ctx = new PluginStoreClassesDataContext()) {
-          return (from plugin in ctx.Plugins
-                  select MakePluginDescription(ctx, plugin)).ToList();
-        }
-      }
-    }
-
-    public byte[] PluginFile(PluginDescription pluginDescription) {
-      using (var ctx = new PluginStoreClassesDataContext()) {
-        return GetExistingPlugin(ctx, pluginDescription.Name, pluginDescription.Version).PluginPackage.Data.ToArray();
-      }
-    }
-
-    public void Persist(PluginDescription pluginDescription, byte[] pluginPackage) {
-      using (var ctx = new PluginStoreClassesDataContext()) {
-        try {
-          using (var transaction = new TransactionScope()) {
-            Plugin pluginEntity = InsertOrUpdatePlugin(ctx, pluginDescription);
-            if (pluginEntity.PluginPackage == null) {
-              // insert
-              pluginEntity.PluginPackage = MakePluginPackage(pluginEntity, pluginPackage);
-            } else {
-              // update
-              pluginEntity.PluginPackage.Data = pluginPackage;
-            }
-            ctx.SubmitChanges();
-            transaction.Complete();
-          }
-        }
-        catch (SqlException ex) {
-          throw new ArgumentException("Something went wrong while trying to persist plugin", ex);
-        }
-        catch (InvalidOperationException ex) {
-          throw new ArgumentException("Something went wrong while trying to persist plugin", ex);
-        }
-      }
-    }
-
-    public void Persist(ProductDescription product) {
-      using (var ctx = new PluginStoreClassesDataContext()) {
-        try {
-          using (var transaction = new TransactionScope()) {
-            foreach (var plugin in product.Plugins) {
-              var pluginEntity = GetExistingPlugin(ctx, plugin.Name, plugin.Version);
-              UpdatePlugin(ctx, pluginEntity, plugin);
-            }
-            InsertOrUpdateProduct(ctx, product);
-            ctx.SubmitChanges();
-            transaction.Complete();
-          }
-        }
-        catch (SqlException ex) {
-          throw new ArgumentException("Something went wrong while trying to persist product", ex);
-        }
-        catch (InvalidOperationException ex) {
-          throw new ArgumentException("Something went wrong while trying to persist product", ex);
-        }
-      }
-    }
-
-    #endregion
-
-    #region insert/update product
-    private void InsertOrUpdateProduct(PluginStoreClassesDataContext ctx, ProductDescription product) {
-      var productEntity = (from p in ctx.Products
-                           where p.Name == product.Name
-                           where p.Version == product.Version.ToString()
-                           select p).FirstOrDefault() ?? MakeProductFromDescription(product);
-
-      if (productEntity.Id <= 0) {
-        ctx.Products.InsertOnSubmit(productEntity);
-        ctx.SubmitChanges();
-      }
-
-      DeleteOldPlugins(ctx, productEntity);
-
-      foreach (var plugin in product.Plugins) {
-        var existingPlugin = GetExistingPlugin(ctx, plugin.Name, plugin.Version);
-        ProductPlugin prodPlugin = new ProductPlugin();
-        prodPlugin.PluginId = existingPlugin.Id;
-        prodPlugin.ProductId = productEntity.Id;
-        ctx.ProductPlugins.InsertOnSubmit(prodPlugin);
-      }
-    }
-
-    private void DeleteOldPlugins(PluginStoreClassesDataContext ctx, Product productEntity) {
-      var oldPlugins = (from p in ctx.ProductPlugins
-                        where p.ProductId == productEntity.Id
-                        select p).ToList();
-      ctx.ProductPlugins.DeleteAllOnSubmit(oldPlugins);
-      ctx.SubmitChanges();
-    }
-    #endregion
-
-    #region insert/update plugins
-    private Plugin InsertOrUpdatePlugin(PluginStoreClassesDataContext ctx, PluginDescription pluginDescription) {
-      var pluginEntity = (from p in ctx.Plugins
-                          where p.Name == pluginDescription.Name
-                          where p.Version == pluginDescription.Version.ToString()
-                          select p).FirstOrDefault() ?? MakePluginFromDescription(pluginDescription);
-
-      if (pluginEntity.Id <= 0) {
-        ctx.Plugins.InsertOnSubmit(pluginEntity);
-        ctx.SubmitChanges();
-      }
-
-      UpdatePlugin(ctx, pluginEntity, pluginDescription);
-      return pluginEntity;
-    }
-
-    private void UpdatePlugin(PluginStoreClassesDataContext ctx, Plugin pluginEntity, PluginDescription pluginDescription) {
-      // delete cached entry
-      if (pluginDescriptions.ContainsKey(pluginEntity)) pluginDescriptions.Remove(pluginEntity);
-
-      DeleteOldDependencies(ctx, pluginEntity);
-
-      foreach (var dependency in pluginDescription.Dependencies) {
-        var dependencyEntity = GetExistingPlugin(ctx, dependency.Name, dependency.Version);
-        Dependency d = new Dependency();
-        d.PluginId = pluginEntity.Id;
-        d.DependencyId = dependencyEntity.Id;
-        ctx.Dependencies.InsertOnSubmit(d);
-      }
-    }
-
-
-
-    private void DeleteOldDependencies(PluginStoreClassesDataContext ctx, Plugin pluginEntity) {
-      var oldDependencies = (from dep in ctx.Dependencies
-                             where dep.PluginId == pluginEntity.Id
-                             select dep).ToList();
-
-      ctx.Dependencies.DeleteAllOnSubmit(oldDependencies);
-      ctx.SubmitChanges();
-    }
-    #endregion
-
-    #region product <-> productDescription transformation
-    private ProductDescription MakeProductDescription(PluginStoreClassesDataContext ctx, Product p, IQueryable<Plugin> plugins) {
-      var desc = new ProductDescription(p.Name, new Version(p.Version), from plugin in plugins
-                                                                        select MakePluginDescription(ctx, plugin));
-      return desc;
-    }
-    private Product MakeProductFromDescription(ProductDescription desc) {
-      var product = new Product();
-      product.Name = desc.Name;
-      product.Version = desc.Version.ToString();
-      return product;
-    }
-    #endregion
-
-    #region plugin <-> pluginDescription transformation
-    // cache for plugin descriptions
-    private Dictionary<Plugin, PluginDescription> pluginDescriptions = new Dictionary<Plugin, PluginDescription>();
-    private PluginDescription MakePluginDescription(PluginStoreClassesDataContext ctx, Plugin plugin) {
-      if (!pluginDescriptions.ContainsKey(plugin)) {
-        // no cached description -> create new
-        var desc = new PluginDescription(plugin.Name, new Version(plugin.Version), from dep in GetDependencies(ctx, plugin)
-                                                                                   select MakePluginDescription(ctx, dep));
-        pluginDescriptions[plugin] = desc;
-      }
-      return pluginDescriptions[plugin];
-    }
-
-    private Plugin MakePluginFromDescription(PluginDescription pluginDescription) {
-      var plugin = new Plugin();
-      plugin.Name = pluginDescription.Name;
-      plugin.Version = pluginDescription.Version.ToString();
-      return plugin;
-    }
-
-    private PluginPackage MakePluginPackage(Plugin plugin, byte[] pluginPackage) {
-      var package = new PluginPackage();
-      package.Data = pluginPackage;
-      package.PluginId = plugin.Id;
-      package.FileName = string.Empty;
-      return package;
-    }
-
-    #endregion
-
-    #region helper queries
-    private Plugin GetExistingPlugin(PluginStoreClassesDataContext ctx, string name, Version version) {
-      return (from p in ctx.Plugins
-              where p.Name == name
-              where p.Version == version.ToString()
-              select p).Single();
-    }
-
-    private IEnumerable<Plugin> GetDependencies(PluginStoreClassesDataContext ctx, Plugin plugin) {
-      return from pair in ctx.Dependencies
-             from dependency in ctx.Plugins
-             where pair.PluginId == plugin.Id
-             where pair.DependencyId == dependency.Id
-             select dependency;
-    }
-    #endregion
-  }
-}
Index: anches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.DataAccess/ProductDescription.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.DataAccess/ProductDescription.cs	(revision 2803)
+++ 	(revision )
@@ -1,36 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Runtime.Serialization;
-
-namespace HeuristicLab.Services.Deployment.DataAccess {
-  [DataContract(Name = "ProductDescription")]
-  public class ProductDescription {
-    [DataMember(Name = "Name")]
-    private string name;
-    public string Name {
-      get { return name; }
-    }
-
-    [DataMember(Name = "Version")]
-    private Version version;
-    public Version Version {
-      get { return version; }
-    }
-
-    [DataMember(Name = "Plugins")]
-    private IEnumerable<PluginDescription> plugins;
-    public IEnumerable<PluginDescription> Plugins {
-      get { return plugins; }
-    }
-
-    public ProductDescription(string name, Version version, IEnumerable<PluginDescription> plugins) {
-      this.name = name;
-      this.version = version;
-      this.plugins = new List<PluginDescription>(plugins).AsReadOnly();
-    }
-  
-    public ProductDescription(string name, Version version) : this(name, version, Enumerable.Empty<PluginDescription>()) { }
-  }
-}
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/HeuristicLab.Services.Deployment.Test.csproj
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/HeuristicLab.Services.Deployment.Test.csproj	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/HeuristicLab.Services.Deployment.Test.csproj	(revision 2804)
@@ -104,10 +104,12 @@
     <None Include="Properties\DataSources\HeuristicLab.Services.Deployment.DataContract.PluginDescription.datasource" />
     <None Include="Properties\DataSources\HeuristicLab.Services.Deployment.DataContract.ProductDescription.datasource" />
-    <None Include="Service References\AdminService\HeuristicLab.Services.Deployment.DataAccess.xsd" />
+    <None Include="Properties\DataSources\HeuristicLab.Services.Deployment.PluginDescription.datasource" />
+    <None Include="Properties\DataSources\HeuristicLab.Services.Deployment.ProductDescription.datasource" />
+    <None Include="Service References\AdminService\HeuristicLab.Services.Deployment.xsd" />
     <None Include="Service References\AdminService\service.wsdl" />
     <None Include="Service References\AdminService\service.xsd" />
     <None Include="Service References\AdminService\service1.xsd" />
     <None Include="Service References\AdminService\System.xsd" />
-    <None Include="Service References\UpdateService\HeuristicLab.Services.Deployment.DataAccess.xsd" />
+    <None Include="Service References\UpdateService\HeuristicLab.Services.Deployment.xsd" />
     <None Include="Service References\UpdateService\service.wsdl" />
     <None Include="Service References\UpdateService\service.xsd" />
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Properties/DataSources/HeuristicLab.Services.Deployment.PluginDescription.datasource
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Properties/DataSources/HeuristicLab.Services.Deployment.PluginDescription.datasource	(revision 2804)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Properties/DataSources/HeuristicLab.Services.Deployment.PluginDescription.datasource	(revision 2804)
@@ -0,0 +1,10 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!--
+    This file is automatically generated by Visual Studio .Net. It is 
+    used to store generic object data source configuration information.  
+    Renaming the file extension or editing the content of this file may   
+    cause the file to be unrecognizable by the program.
+-->
+<GenericObjectDataSource DisplayName="PluginDescription" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
+   <TypeInfo>HeuristicLab.Services.Deployment.PluginDescription, HeuristicLab.Services.Deployment, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
+</GenericObjectDataSource>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Properties/DataSources/HeuristicLab.Services.Deployment.ProductDescription.datasource
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Properties/DataSources/HeuristicLab.Services.Deployment.ProductDescription.datasource	(revision 2804)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Properties/DataSources/HeuristicLab.Services.Deployment.ProductDescription.datasource	(revision 2804)
@@ -0,0 +1,10 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!--
+    This file is automatically generated by Visual Studio .Net. It is 
+    used to store generic object data source configuration information.  
+    Renaming the file extension or editing the content of this file may   
+    cause the file to be unrecognizable by the program.
+-->
+<GenericObjectDataSource DisplayName="ProductDescription" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
+   <TypeInfo>HeuristicLab.Services.Deployment.ProductDescription, HeuristicLab.Services.Deployment, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
+</GenericObjectDataSource>
Index: anches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/HeuristicLab.Services.Deployment.DataAccess.xsd
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/HeuristicLab.Services.Deployment.DataAccess.xsd	(revision 2803)
+++ 	(revision )
@@ -1,26 +1,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" xmlns:xs="http://www.w3.org/2001/XMLSchema">
-  <xs:import namespace="http://schemas.datacontract.org/2004/07/System" />
-  <xs:complexType name="ProductDescription">
-    <xs:sequence>
-      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
-      <xs:element minOccurs="0" name="Plugins" nillable="true" type="tns:ArrayOfPluginDescription" />
-      <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/System" minOccurs="0" name="Version" nillable="true" type="q1:Version" />
-    </xs:sequence>
-  </xs:complexType>
-  <xs:element name="ProductDescription" nillable="true" type="tns:ProductDescription" />
-  <xs:complexType name="ArrayOfPluginDescription">
-    <xs:sequence>
-      <xs:element minOccurs="0" maxOccurs="unbounded" name="PluginDescription" nillable="true" type="tns:PluginDescription" />
-    </xs:sequence>
-  </xs:complexType>
-  <xs:element name="ArrayOfPluginDescription" nillable="true" type="tns:ArrayOfPluginDescription" />
-  <xs:complexType name="PluginDescription">
-    <xs:sequence>
-      <xs:element minOccurs="0" name="Dependencies" nillable="true" type="tns:ArrayOfPluginDescription" />
-      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
-      <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/System" minOccurs="0" name="Version" nillable="true" type="q2:Version" />
-    </xs:sequence>
-  </xs:complexType>
-  <xs:element name="PluginDescription" nillable="true" type="tns:PluginDescription" />
-</xs:schema>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/HeuristicLab.Services.Deployment.xsd
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/HeuristicLab.Services.Deployment.xsd	(revision 2804)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/HeuristicLab.Services.Deployment.xsd	(revision 2804)
@@ -0,0 +1,26 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xs:import namespace="http://schemas.datacontract.org/2004/07/System" />
+  <xs:complexType name="ProductDescription">
+    <xs:sequence>
+      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
+      <xs:element minOccurs="0" name="Plugins" nillable="true" type="tns:ArrayOfPluginDescription" />
+      <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/System" minOccurs="0" name="Version" nillable="true" type="q1:Version" />
+    </xs:sequence>
+  </xs:complexType>
+  <xs:element name="ProductDescription" nillable="true" type="tns:ProductDescription" />
+  <xs:complexType name="ArrayOfPluginDescription">
+    <xs:sequence>
+      <xs:element minOccurs="0" maxOccurs="unbounded" name="PluginDescription" nillable="true" type="tns:PluginDescription" />
+    </xs:sequence>
+  </xs:complexType>
+  <xs:element name="ArrayOfPluginDescription" nillable="true" type="tns:ArrayOfPluginDescription" />
+  <xs:complexType name="PluginDescription">
+    <xs:sequence>
+      <xs:element minOccurs="0" name="Dependencies" nillable="true" type="tns:ArrayOfPluginDescription" />
+      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
+      <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/System" minOccurs="0" name="Version" nillable="true" type="q2:Version" />
+    </xs:sequence>
+  </xs:complexType>
+  <xs:element name="PluginDescription" nillable="true" type="tns:PluginDescription" />
+</xs:schema>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/Reference.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/Reference.cs	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/Reference.cs	(revision 2804)
@@ -17,8 +17,8 @@
         
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAdmin/DeployProduct", ReplyAction="http://tempuri.org/IAdmin/DeployProductResponse")]
-        void DeployProduct(HeuristicLab.Services.Deployment.DataAccess.ProductDescription product);
+        void DeployProduct(HeuristicLab.Services.Deployment.ProductDescription product);
         
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAdmin/DeployPlugin", ReplyAction="http://tempuri.org/IAdmin/DeployPluginResponse")]
-        void DeployPlugin(HeuristicLab.Services.Deployment.DataAccess.PluginDescription plugin, byte[] zipFile);
+        void DeployPlugin(HeuristicLab.Services.Deployment.PluginDescription plugin, byte[] zipFile);
     }
     
@@ -50,9 +50,9 @@
         }
         
-        public void DeployProduct(HeuristicLab.Services.Deployment.DataAccess.ProductDescription product) {
+        public void DeployProduct(HeuristicLab.Services.Deployment.ProductDescription product) {
             base.Channel.DeployProduct(product);
         }
         
-        public void DeployPlugin(HeuristicLab.Services.Deployment.DataAccess.PluginDescription plugin, byte[] zipFile) {
+        public void DeployPlugin(HeuristicLab.Services.Deployment.PluginDescription plugin, byte[] zipFile) {
             base.Channel.DeployPlugin(plugin, zipFile);
         }
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/Reference.svcmap
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/Reference.svcmap	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/Reference.svcmap	(revision 2804)
@@ -24,5 +24,5 @@
     <MetadataFile FileName="service.xsd" MetadataType="Schema" ID="c0d733c0-fa7a-4965-bf67-e04efdf79732" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Admin/mex" />
     <MetadataFile FileName="service1.xsd" MetadataType="Schema" ID="8b323fa0-af4b-4db2-95c7-caf4621ded43" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Admin/mex" />
-    <MetadataFile FileName="HeuristicLab.Services.Deployment.DataAccess.xsd" MetadataType="Schema" ID="45a12626-e280-4b27-a897-c66de0c21595" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Admin/mex" />
+    <MetadataFile FileName="HeuristicLab.Services.Deployment.xsd" MetadataType="Schema" ID="b359957d-39eb-4fda-b855-9cf0efe56074" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Admin/mex" />
     <MetadataFile FileName="System.xsd" MetadataType="Schema" ID="de5b0b79-4ace-49d6-9d08-a352d353beef" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Admin/mex" />
   </Metadata>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/service.wsdl
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/service.wsdl	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/service.wsdl	(revision 2804)
@@ -187,5 +187,5 @@
       <xsd:import namespace="http://tempuri.org/" />
       <xsd:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
-      <xsd:import namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" />
+      <xsd:import namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" />
       <xsd:import namespace="http://schemas.datacontract.org/2004/07/System" />
     </xsd:schema>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/service.xsd
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/service.xsd	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/AdminService/service.xsd	(revision 2804)
@@ -1,9 +1,9 @@
 ﻿<?xml version="1.0" encoding="utf-8"?>
 <xs:schema xmlns:tns="http://tempuri.org/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
-  <xs:import namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" />
+  <xs:import namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" />
   <xs:element name="DeployProduct">
     <xs:complexType>
       <xs:sequence>
-        <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" minOccurs="0" name="product" nillable="true" type="q1:ProductDescription" />
+        <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" minOccurs="0" name="product" nillable="true" type="q1:ProductDescription" />
       </xs:sequence>
     </xs:complexType>
@@ -17,5 +17,5 @@
     <xs:complexType>
       <xs:sequence>
-        <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" minOccurs="0" name="plugin" nillable="true" type="q2:PluginDescription" />
+        <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" minOccurs="0" name="plugin" nillable="true" type="q2:PluginDescription" />
         <xs:element minOccurs="0" name="zipFile" nillable="true" type="xs:base64Binary" />
       </xs:sequence>
Index: anches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/HeuristicLab.Services.Deployment.DataAccess.xsd
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/HeuristicLab.Services.Deployment.DataAccess.xsd	(revision 2803)
+++ 	(revision )
@@ -1,32 +1,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" xmlns:xs="http://www.w3.org/2001/XMLSchema">
-  <xs:import namespace="http://schemas.datacontract.org/2004/07/System" />
-  <xs:complexType name="PluginDescription">
-    <xs:sequence>
-      <xs:element minOccurs="0" name="Dependencies" nillable="true" type="tns:ArrayOfPluginDescription" />
-      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
-      <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/System" minOccurs="0" name="Version" nillable="true" type="q1:Version" />
-    </xs:sequence>
-  </xs:complexType>
-  <xs:element name="PluginDescription" nillable="true" type="tns:PluginDescription" />
-  <xs:complexType name="ArrayOfPluginDescription">
-    <xs:sequence>
-      <xs:element minOccurs="0" maxOccurs="unbounded" name="PluginDescription" nillable="true" type="tns:PluginDescription" />
-    </xs:sequence>
-  </xs:complexType>
-  <xs:element name="ArrayOfPluginDescription" nillable="true" type="tns:ArrayOfPluginDescription" />
-  <xs:complexType name="ArrayOfProductDescription">
-    <xs:sequence>
-      <xs:element minOccurs="0" maxOccurs="unbounded" name="ProductDescription" nillable="true" type="tns:ProductDescription" />
-    </xs:sequence>
-  </xs:complexType>
-  <xs:element name="ArrayOfProductDescription" nillable="true" type="tns:ArrayOfProductDescription" />
-  <xs:complexType name="ProductDescription">
-    <xs:sequence>
-      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
-      <xs:element minOccurs="0" name="Plugins" nillable="true" type="tns:ArrayOfPluginDescription" />
-      <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/System" minOccurs="0" name="Version" nillable="true" type="q2:Version" />
-    </xs:sequence>
-  </xs:complexType>
-  <xs:element name="ProductDescription" nillable="true" type="tns:ProductDescription" />
-</xs:schema>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/HeuristicLab.Services.Deployment.xsd
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/HeuristicLab.Services.Deployment.xsd	(revision 2804)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/HeuristicLab.Services.Deployment.xsd	(revision 2804)
@@ -0,0 +1,32 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xs:import namespace="http://schemas.datacontract.org/2004/07/System" />
+  <xs:complexType name="PluginDescription">
+    <xs:sequence>
+      <xs:element minOccurs="0" name="Dependencies" nillable="true" type="tns:ArrayOfPluginDescription" />
+      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
+      <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/System" minOccurs="0" name="Version" nillable="true" type="q1:Version" />
+    </xs:sequence>
+  </xs:complexType>
+  <xs:element name="PluginDescription" nillable="true" type="tns:PluginDescription" />
+  <xs:complexType name="ArrayOfPluginDescription">
+    <xs:sequence>
+      <xs:element minOccurs="0" maxOccurs="unbounded" name="PluginDescription" nillable="true" type="tns:PluginDescription" />
+    </xs:sequence>
+  </xs:complexType>
+  <xs:element name="ArrayOfPluginDescription" nillable="true" type="tns:ArrayOfPluginDescription" />
+  <xs:complexType name="ArrayOfProductDescription">
+    <xs:sequence>
+      <xs:element minOccurs="0" maxOccurs="unbounded" name="ProductDescription" nillable="true" type="tns:ProductDescription" />
+    </xs:sequence>
+  </xs:complexType>
+  <xs:element name="ArrayOfProductDescription" nillable="true" type="tns:ArrayOfProductDescription" />
+  <xs:complexType name="ProductDescription">
+    <xs:sequence>
+      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
+      <xs:element minOccurs="0" name="Plugins" nillable="true" type="tns:ArrayOfPluginDescription" />
+      <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/System" minOccurs="0" name="Version" nillable="true" type="q2:Version" />
+    </xs:sequence>
+  </xs:complexType>
+  <xs:element name="ProductDescription" nillable="true" type="tns:ProductDescription" />
+</xs:schema>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/Reference.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/Reference.cs	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/Reference.cs	(revision 2804)
@@ -17,11 +17,11 @@
         
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IUpdate/GetPlugin", ReplyAction="http://tempuri.org/IUpdate/GetPluginResponse")]
-        byte[] GetPlugin(HeuristicLab.Services.Deployment.DataAccess.PluginDescription description);
+        byte[] GetPlugin(HeuristicLab.Services.Deployment.PluginDescription description);
         
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IUpdate/GetProducts", ReplyAction="http://tempuri.org/IUpdate/GetProductsResponse")]
-        HeuristicLab.Services.Deployment.DataAccess.ProductDescription[] GetProducts();
+        HeuristicLab.Services.Deployment.ProductDescription[] GetProducts();
         
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IUpdate/GetPlugins", ReplyAction="http://tempuri.org/IUpdate/GetPluginsResponse")]
-        HeuristicLab.Services.Deployment.DataAccess.PluginDescription[] GetPlugins();
+        HeuristicLab.Services.Deployment.PluginDescription[] GetPlugins();
     }
     
@@ -53,13 +53,13 @@
         }
         
-        public byte[] GetPlugin(HeuristicLab.Services.Deployment.DataAccess.PluginDescription description) {
+        public byte[] GetPlugin(HeuristicLab.Services.Deployment.PluginDescription description) {
             return base.Channel.GetPlugin(description);
         }
         
-        public HeuristicLab.Services.Deployment.DataAccess.ProductDescription[] GetProducts() {
+        public HeuristicLab.Services.Deployment.ProductDescription[] GetProducts() {
             return base.Channel.GetProducts();
         }
         
-        public HeuristicLab.Services.Deployment.DataAccess.PluginDescription[] GetPlugins() {
+        public HeuristicLab.Services.Deployment.PluginDescription[] GetPlugins() {
             return base.Channel.GetPlugins();
         }
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/Reference.svcmap
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/Reference.svcmap	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/Reference.svcmap	(revision 2804)
@@ -24,5 +24,5 @@
     <MetadataFile FileName="service.xsd" MetadataType="Schema" ID="3ecb07b5-a96d-4407-89dd-1e042527a912" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Update/mex" />
     <MetadataFile FileName="service1.xsd" MetadataType="Schema" ID="a49c6318-2559-4c8b-901c-d677ebcea2cb" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Update/mex" />
-    <MetadataFile FileName="HeuristicLab.Services.Deployment.DataAccess.xsd" MetadataType="Schema" ID="4c81cb11-6068-40b4-b3a4-63cb202f34e8" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Update/mex" />
+    <MetadataFile FileName="HeuristicLab.Services.Deployment.xsd" MetadataType="Schema" ID="95669cc5-5ec5-467d-9a09-464c14558b64" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Update/mex" />
     <MetadataFile FileName="System.xsd" MetadataType="Schema" ID="c6636f98-e644-40dd-a862-3a38c2950f79" SourceId="1" SourceUrl="http://localhost:8731/Design_Time_Addresses/HeuristicLab.Services.Deployment/Update/mex" />
   </Metadata>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/service.wsdl
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/service.wsdl	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/service.wsdl	(revision 2804)
@@ -225,5 +225,5 @@
       <xsd:import namespace="http://tempuri.org/" />
       <xsd:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
-      <xsd:import namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" />
+      <xsd:import namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" />
       <xsd:import namespace="http://schemas.datacontract.org/2004/07/System" />
     </xsd:schema>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/service.xsd
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/service.xsd	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.Test/Service References/UpdateService/service.xsd	(revision 2804)
@@ -1,9 +1,9 @@
 ﻿<?xml version="1.0" encoding="utf-8"?>
 <xs:schema xmlns:tns="http://tempuri.org/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
-  <xs:import namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" />
+  <xs:import namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" />
   <xs:element name="GetPlugin">
     <xs:complexType>
       <xs:sequence>
-        <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" minOccurs="0" name="description" nillable="true" type="q1:PluginDescription" />
+        <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" minOccurs="0" name="description" nillable="true" type="q1:PluginDescription" />
       </xs:sequence>
     </xs:complexType>
@@ -24,5 +24,5 @@
     <xs:complexType>
       <xs:sequence>
-        <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" minOccurs="0" name="GetProductsResult" nillable="true" type="q2:ArrayOfProductDescription" />
+        <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" minOccurs="0" name="GetProductsResult" nillable="true" type="q2:ArrayOfProductDescription" />
       </xs:sequence>
     </xs:complexType>
@@ -36,5 +36,5 @@
     <xs:complexType>
       <xs:sequence>
-        <xs:element xmlns:q3="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment.DataAccess" minOccurs="0" name="GetPluginsResult" nillable="true" type="q3:ArrayOfPluginDescription" />
+        <xs:element xmlns:q3="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment" minOccurs="0" name="GetPluginsResult" nillable="true" type="q3:ArrayOfPluginDescription" />
       </xs:sequence>
     </xs:complexType>
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/HeuristicLab.Services.Deployment.csproj
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/HeuristicLab.Services.Deployment.csproj	(revision 2803)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/HeuristicLab.Services.Deployment.csproj	(revision 2804)
@@ -46,4 +46,5 @@
       <RequiredTargetFramework>3.0</RequiredTargetFramework>
     </Reference>
+    <Reference Include="System.Transactions" />
     <Reference Include="System.Xml" />
     <Reference Include="System.Xml.Linq">
@@ -55,4 +56,7 @@
     <Compile Include="IAdmin.cs" />
     <Compile Include="IUpdate.cs" />
+    <Compile Include="PluginDescription.cs" />
+    <Compile Include="PluginStore.cs" />
+    <Compile Include="ProductDescription.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\Settings.Designer.cs">
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/PluginDescription.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/PluginDescription.cs	(revision 2804)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/PluginDescription.cs	(revision 2804)
@@ -0,0 +1,40 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Runtime.Serialization;
+
+namespace HeuristicLab.Services.Deployment {
+  [DataContract(Name = "PluginDescription")]
+  public class PluginDescription  {
+
+    [DataMember(Name = "Name")]
+    private string name;
+    public string Name {
+      get { return name; }
+    }
+
+    [DataMember(Name = "Version")]
+    private Version version;
+    public Version Version {
+      get { return version; }
+    }
+
+
+    [DataMember(Name = "Dependencies")]
+    private List<PluginDescription> dependencies;
+    public List<PluginDescription> Dependencies {
+      get { return dependencies; }
+    }
+
+    public PluginDescription(string name, Version version, IEnumerable<PluginDescription> dependencies) {
+      this.name = name;
+      this.version = version;
+      this.dependencies = new List<PluginDescription>(dependencies); //.AsReadOnly();
+    }
+
+    public PluginDescription(string name, Version version)
+      : this(name, version, Enumerable.Empty<PluginDescription>()) {
+    }
+  }
+}
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/PluginStore.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/PluginStore.cs	(revision 2804)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/PluginStore.cs	(revision 2804)
@@ -0,0 +1,231 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Data.Common;
+using System.Transactions;
+using System.Data.SqlClient;
+using HeuristicLab.Services.Deployment.DataAccess;
+
+namespace HeuristicLab.Services.Deployment {
+  public class PluginStore {
+
+    public PluginStore() {
+    }
+
+    #region context creating members
+    public IEnumerable<ProductDescription> Products {
+      get {
+        using (var ctx = new PluginStoreClassesDataContext()) {
+          return (from p in ctx.Products
+                  let plugins = from pair in ctx.ProductPlugins
+                                from plugin in ctx.Plugins
+                                where pair.ProductId == p.Id
+                                where plugin.Id == pair.PluginId
+                                select plugin
+                  select MakeProductDescription(ctx, p, plugins)).ToList();
+        }
+      }
+    }
+
+    public IEnumerable<PluginDescription> Plugins {
+      get {
+        using (var ctx = new PluginStoreClassesDataContext()) {
+          return (from plugin in ctx.Plugins
+                  select MakePluginDescription(ctx, plugin)).ToList();
+        }
+      }
+    }
+
+    public byte[] PluginFile(PluginDescription pluginDescription) {
+      using (var ctx = new PluginStoreClassesDataContext()) {
+        return GetExistingPlugin(ctx, pluginDescription.Name, pluginDescription.Version).PluginPackage.Data.ToArray();
+      }
+    }
+
+    public void Persist(PluginDescription pluginDescription, byte[] pluginPackage) {
+      using (var ctx = new PluginStoreClassesDataContext()) {
+        try {
+          using (var transaction = new TransactionScope()) {
+            Plugin pluginEntity = InsertOrUpdatePlugin(ctx, pluginDescription);
+            if (pluginEntity.PluginPackage == null) {
+              // insert
+              pluginEntity.PluginPackage = MakePluginPackage(pluginEntity, pluginPackage);
+            } else {
+              // update
+              pluginEntity.PluginPackage.Data = pluginPackage;
+            }
+            ctx.SubmitChanges();
+            transaction.Complete();
+          }
+        }
+        catch (SqlException ex) {
+          throw new ArgumentException("Something went wrong while trying to persist plugin", ex);
+        }
+        catch (InvalidOperationException ex) {
+          throw new ArgumentException("Something went wrong while trying to persist plugin", ex);
+        }
+      }
+    }
+
+    public void Persist(ProductDescription productDescription) {
+      using (var ctx = new PluginStoreClassesDataContext()) {
+        try {
+          using (var transaction = new TransactionScope()) {
+            foreach (var plugin in productDescription.Plugins) {
+              var pluginEntity = GetExistingPlugin(ctx, plugin.Name, plugin.Version);
+              UpdatePlugin(ctx, pluginEntity, plugin);
+            }
+            InsertOrUpdateProduct(ctx, productDescription);
+            ctx.SubmitChanges();
+            transaction.Complete();
+          }
+        }
+        catch (SqlException ex) {
+          throw new ArgumentException("Something went wrong while trying to persist product", ex);
+        }
+        catch (InvalidOperationException ex) {
+          throw new ArgumentException("Something went wrong while trying to persist product", ex);
+        }
+      }
+    }
+
+    #endregion
+
+    #region insert/update product
+    private void InsertOrUpdateProduct(PluginStoreClassesDataContext ctx, ProductDescription product) {
+      var productEntity = (from p in ctx.Products
+                           where p.Name == product.Name
+                           where p.Version == product.Version.ToString()
+                           select p).FirstOrDefault() ?? MakeProductFromDescription(product);
+
+      if (productEntity.Id <= 0) {
+        ctx.Products.InsertOnSubmit(productEntity);
+        ctx.SubmitChanges();
+      }
+
+      DeleteOldPlugins(ctx, productEntity);
+
+      foreach (var plugin in product.Plugins) {
+        var existingPlugin = GetExistingPlugin(ctx, plugin.Name, plugin.Version);
+        ProductPlugin prodPlugin = new ProductPlugin();
+        prodPlugin.PluginId = existingPlugin.Id;
+        prodPlugin.ProductId = productEntity.Id;
+        ctx.ProductPlugins.InsertOnSubmit(prodPlugin);
+      }
+    }
+
+    private void DeleteOldPlugins(PluginStoreClassesDataContext ctx, Product productEntity) {
+      var oldPlugins = (from p in ctx.ProductPlugins
+                        where p.ProductId == productEntity.Id
+                        select p).ToList();
+      ctx.ProductPlugins.DeleteAllOnSubmit(oldPlugins);
+      ctx.SubmitChanges();
+    }
+    #endregion
+
+    #region insert/update plugins
+    private Plugin InsertOrUpdatePlugin(PluginStoreClassesDataContext ctx, PluginDescription pluginDescription) {
+      var pluginEntity = (from p in ctx.Plugins
+                          where p.Name == pluginDescription.Name
+                          where p.Version == pluginDescription.Version.ToString()
+                          select p).FirstOrDefault() ?? MakePluginFromDescription(pluginDescription);
+
+      if (pluginEntity.Id <= 0) {
+        ctx.Plugins.InsertOnSubmit(pluginEntity);
+        ctx.SubmitChanges();
+      }
+
+      UpdatePlugin(ctx, pluginEntity, pluginDescription);
+      return pluginEntity;
+    }
+
+    private void UpdatePlugin(PluginStoreClassesDataContext ctx, Plugin pluginEntity, PluginDescription pluginDescription) {
+      // delete cached entry
+      if (pluginDescriptions.ContainsKey(pluginEntity)) pluginDescriptions.Remove(pluginEntity);
+
+      DeleteOldDependencies(ctx, pluginEntity);
+
+      foreach (var dependency in pluginDescription.Dependencies) {
+        var dependencyEntity = GetExistingPlugin(ctx, dependency.Name, dependency.Version);
+        Dependency d = new Dependency();
+        d.PluginId = pluginEntity.Id;
+        d.DependencyId = dependencyEntity.Id;
+        ctx.Dependencies.InsertOnSubmit(d);
+      }
+    }
+
+
+
+    private void DeleteOldDependencies(PluginStoreClassesDataContext ctx, Plugin pluginEntity) {
+      var oldDependencies = (from dep in ctx.Dependencies
+                             where dep.PluginId == pluginEntity.Id
+                             select dep).ToList();
+
+      ctx.Dependencies.DeleteAllOnSubmit(oldDependencies);
+      ctx.SubmitChanges();
+    }
+    #endregion
+
+    #region product <-> productDescription transformation
+    private ProductDescription MakeProductDescription(PluginStoreClassesDataContext ctx, Product p, IQueryable<Plugin> plugins) {
+      var desc = new ProductDescription(p.Name, new Version(p.Version), from plugin in plugins
+                                                                        select MakePluginDescription(ctx, plugin));
+      return desc;
+    }
+    private Product MakeProductFromDescription(ProductDescription desc) {
+      var product = new Product();
+      product.Name = desc.Name;
+      product.Version = desc.Version.ToString();
+      return product;
+    }
+    #endregion
+
+    #region plugin <-> pluginDescription transformation
+    // cache for plugin descriptions
+    private Dictionary<Plugin, PluginDescription> pluginDescriptions = new Dictionary<Plugin, PluginDescription>();
+    private PluginDescription MakePluginDescription(PluginStoreClassesDataContext ctx, Plugin plugin) {
+      if (!pluginDescriptions.ContainsKey(plugin)) {
+        // no cached description -> create new
+        var desc = new PluginDescription(plugin.Name, new Version(plugin.Version), from dep in GetDependencies(ctx, plugin)
+                                                                                   select MakePluginDescription(ctx, dep));
+        pluginDescriptions[plugin] = desc;
+      }
+      return pluginDescriptions[plugin];
+    }
+
+    private Plugin MakePluginFromDescription(PluginDescription pluginDescription) {
+      var plugin = new Plugin();
+      plugin.Name = pluginDescription.Name;
+      plugin.Version = pluginDescription.Version.ToString();
+      return plugin;
+    }
+
+    private PluginPackage MakePluginPackage(Plugin plugin, byte[] pluginPackage) {
+      var package = new PluginPackage();
+      package.Data = pluginPackage;
+      package.PluginId = plugin.Id;
+      package.FileName = string.Empty;
+      return package;
+    }
+
+    #endregion
+
+    #region helper queries
+    private Plugin GetExistingPlugin(PluginStoreClassesDataContext ctx, string name, Version version) {
+      return (from p in ctx.Plugins
+              where p.Name == name
+              where p.Version == version.ToString()
+              select p).Single();
+    }
+
+    private IEnumerable<Plugin> GetDependencies(PluginStoreClassesDataContext ctx, Plugin plugin) {
+      return from pair in ctx.Dependencies
+             from dependency in ctx.Plugins
+             where pair.PluginId == plugin.Id
+             where pair.DependencyId == dependency.Id
+             select dependency;
+    }
+    #endregion
+  }
+}
Index: /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/ProductDescription.cs
===================================================================
--- /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/ProductDescription.cs	(revision 2804)
+++ /branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment/ProductDescription.cs	(revision 2804)
@@ -0,0 +1,36 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Runtime.Serialization;
+
+namespace HeuristicLab.Services.Deployment {
+  [DataContract(Name = "ProductDescription")]
+  public class ProductDescription {
+    [DataMember(Name = "Name")]
+    private string name;
+    public string Name {
+      get { return name; }
+    }
+
+    [DataMember(Name = "Version")]
+    private Version version;
+    public Version Version {
+      get { return version; }
+    }
+
+    [DataMember(Name = "Plugins")]
+    private IEnumerable<PluginDescription> plugins;
+    public IEnumerable<PluginDescription> Plugins {
+      get { return plugins; }
+    }
+
+    public ProductDescription(string name, Version version, IEnumerable<PluginDescription> plugins) {
+      this.name = name;
+      this.version = version;
+      this.plugins = new List<PluginDescription>(plugins).AsReadOnly();
+    }
+
+    public ProductDescription(string name, Version version) : this(name, version, Enumerable.Empty<PluginDescription>()) { }
+  }
+}
