Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectDao.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectDao.cs	(revision 15379)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectDao.cs	(revision 15379)
@@ -0,0 +1,42 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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;
+using System.Data.Linq;
+using System.Linq;
+
+namespace HeuristicLab.Services.Hive.DataAccess.Daos {
+  public class ProjectDao : GenericDao<Guid, Project> {
+    public ProjectDao(DataContext dataContext) : base(dataContext) { }
+
+    public override Project GetById(Guid id) {
+      return GetByIdQuery(DataContext, id);
+    }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, Project> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid projectId) =>
+        (from project in db.GetTable<Project>()
+         where project.ProjectId == projectId
+         select project).SingleOrDefault());
+    #endregion
+  }
+}
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectPermissionDao.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectPermissionDao.cs	(revision 15379)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectPermissionDao.cs	(revision 15379)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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;
+using System.Collections.Generic;
+using System.Data.Linq;
+using System.Linq;
+
+namespace HeuristicLab.Services.Hive.DataAccess.Daos {
+  public class ProjectPermissionDao : GenericDao<Guid, ProjectPermission> {
+    public ProjectPermissionDao(DataContext dataContext) : base(dataContext) { }
+
+    public override ProjectPermission GetById(Guid id) {
+      throw new NotImplementedException();
+    }
+
+    public IEnumerable<ProjectPermission> GetByProjectId(Guid id) {
+      return GetByProjectIdGetByIdQuery(DataContext, id);
+    }
+
+    public void DeleteByProjectAndGrantedUserId(Guid projectId, IEnumerable<Guid> grantedUserId) {
+      string paramIds = string.Join(",", grantedUserId.Select(x => string.Format("'{0}'", x)));
+      if (!string.IsNullOrWhiteSpace(paramIds)) {
+        string query = string.Format(DeleteByGrantedUserQuery, projectId, paramIds);
+        DataContext.ExecuteCommand(query);
+      }
+    }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, IEnumerable<ProjectPermission>> GetByProjectIdGetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid projectId) =>
+        from projectPermission in db.GetTable<ProjectPermission>()
+        where projectPermission.ProjectId == projectId
+        select projectPermission);
+    #endregion
+
+    #region String queries
+    private const string DeleteByGrantedUserQuery =
+      @"DELETE FROM [ProjectPermission]
+         WHERE ProjectId = '{0}'
+           AND GrantedUserId IN ({1});";
+    #endregion
+  }
+}
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourcePermissionDao.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourcePermissionDao.cs	(revision 15378)
+++ 	(revision )
@@ -1,62 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 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;
-using System.Collections.Generic;
-using System.Data.Linq;
-using System.Linq;
-
-namespace HeuristicLab.Services.Hive.DataAccess.Daos {
-  public class ResourcePermissionDao : GenericDao<Guid, ResourcePermission> {
-    public ResourcePermissionDao(DataContext dataContext) : base(dataContext) { }
-
-    public override ResourcePermission GetById(Guid id) {
-      throw new NotImplementedException();
-    }
-
-    public IEnumerable<ResourcePermission> GetByResourceId(Guid id) {
-      return GetByResourceIdGetByIdQuery(DataContext, id);
-    }
-
-    public void DeleteByResourceAndGrantedUserId(Guid resourceId, IEnumerable<Guid> grantedUserId) {
-      string paramIds = string.Join(",", grantedUserId.Select(x => string.Format("'{0}'", x)));
-      if (!string.IsNullOrWhiteSpace(paramIds)) {
-        string query = string.Format(DeleteByGrantedUserQuery, resourceId, paramIds);
-        DataContext.ExecuteCommand(query);
-      }
-    }
-
-    #region Compiled queries
-    private static readonly Func<DataContext, Guid, IEnumerable<ResourcePermission>> GetByResourceIdGetByIdQuery =
-      CompiledQuery.Compile((DataContext db, Guid resourceId) =>
-        from resourcePermission in db.GetTable<ResourcePermission>()
-        where resourcePermission.ResourceId == resourceId
-        select resourcePermission);
-    #endregion
-
-    #region String queries
-    private const string DeleteByGrantedUserQuery =
-      @"DELETE FROM [ResourcePermission]
-         WHERE ResourceId = '{0}'
-           AND GrantedUserId IN ({1});";
-    #endregion
-  }
-}
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj	(revision 15378)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj	(revision 15379)
@@ -118,7 +118,8 @@
     <Compile Include="Daos\PluginDao.cs" />
     <Compile Include="Daos\PluginDataDao.cs" />
+    <Compile Include="Daos\ProjectDao.cs" />
+    <Compile Include="Daos\ProjectPermissionDao.cs" />
     <Compile Include="Daos\RequiredPluginDao.cs" />
     <Compile Include="Daos\ResourceDao.cs" />
-    <Compile Include="Daos\ResourcePermissionDao.cs" />
     <Compile Include="Daos\SlaveDao.cs" />
     <Compile Include="Daos\SlaveGroupDao.cs" />
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml	(revision 15378)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml	(revision 15379)
@@ -265,5 +265,5 @@
       <Column Name="OwnerUserId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" CanBeNull="false" />
       <Column Name="StartDate" Type="System.DateTime" DbType="DateTime NOT NULL" CanBeNull="false" />
-      <Column Name="EndDate" Type="System.DateTime" DbType="DateTime" CanBeNull="false" />
+      <Column Name="EndDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
       <Association Name="Project_AssignedResource" Member="AssignedResources" ThisKey="ProjectId" OtherKey="ProjectId" Type="AssignedResource" />
       <Association Name="Project_Job" Member="Jobs" ThisKey="ProjectId" OtherKey="ProjectId" Type="Job" />
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.designer.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.designer.cs	(revision 15378)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.designer.cs	(revision 15379)
@@ -5681,5 +5681,5 @@
 		private System.DateTime _StartDate;
 		
-		private System.DateTime _EndDate;
+		private System.Nullable<System.DateTime> _EndDate;
 		
 		private EntitySet<AssignedResource> _AssignedResources;
@@ -5711,5 +5711,5 @@
     partial void OnStartDateChanging(System.DateTime value);
     partial void OnStartDateChanged();
-    partial void OnEndDateChanging(System.DateTime value);
+    partial void OnEndDateChanging(System.Nullable<System.DateTime> value);
     partial void OnEndDateChanged();
     #endregion
@@ -5870,5 +5870,5 @@
 		
 		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EndDate", DbType="DateTime")]
-		public System.DateTime EndDate
+		public System.Nullable<System.DateTime> EndDate
 		{
 			get
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Interfaces/IPersistenceManager.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Interfaces/IPersistenceManager.cs	(revision 15378)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Interfaces/IPersistenceManager.cs	(revision 15379)
@@ -38,7 +38,8 @@
     PluginDao PluginDao { get; }
     PluginDataDao PluginDataDao { get; }
+    ProjectDao ProjectDao { get; }
+    ProjectPermissionDao ProjectPermissionDao { get; }
     RequiredPluginDao RequiredPluginDao { get; }
     ResourceDao ResourceDao { get; }
-    ResourcePermissionDao ResourcePermissionDao { get; }
     SlaveDao SlaveDao { get; }
     SlaveGroupDao SlaveGroupDao { get; }
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Manager/PersistenceManager.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Manager/PersistenceManager.cs	(revision 15378)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Manager/PersistenceManager.cs	(revision 15379)
@@ -73,4 +73,14 @@
     }
 
+    private ProjectDao projectDao;
+    public ProjectDao ProjectDao {
+      get { return projectDao ?? (projectDao = new ProjectDao(dataContext)); }
+    }
+
+    private ProjectPermissionDao resourcePermissionDao;
+    public ProjectPermissionDao ProjectPermissionDao {
+      get { return resourcePermissionDao ?? (resourcePermissionDao = new ProjectPermissionDao(dataContext)); }
+    }
+
     private RequiredPluginDao requiredPluginDao;
     public RequiredPluginDao RequiredPluginDao {
@@ -81,9 +91,4 @@
     public ResourceDao ResourceDao {
       get { return resourceDao ?? (resourceDao = new ResourceDao(dataContext)); }
-    }
-
-    private ResourcePermissionDao resourcePermissionDao;
-    public ResourcePermissionDao ResourcePermissionDao {
-      get { return resourcePermissionDao ?? (resourcePermissionDao = new ResourcePermissionDao(dataContext)); }
     }
 
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Converter.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Converter.cs	(revision 15378)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Converter.cs	(revision 15379)
@@ -333,22 +333,55 @@
     #endregion
 
-    #region ResourcePermission
-    public static DT.ResourcePermission ToDto(this DA.ResourcePermission source) {
-      if (source == null) return null;
-      return new DT.ResourcePermission {
-        ResourceId = source.ResourceId,
+    #region Project
+    public static DT.Project ToDto(this DA.Project source) {
+      if (source == null) return null;
+      return new DT.Project {
+        Id = source.ProjectId,
+        ParentProjectId = source.ParentProjectId,
+        DateCreated = source.DateCreated,
+        Name = source.Name,
+        Description = source.Description,
+        OwnerUserId = source.OwnerUserId,
+        StartDate = source.StartDate,
+        EndDate = source.EndDate
+      };
+    }
+    public static DA.Project ToEntity(this DT.Project source) {
+      if (source == null) return null;
+      var result = new DA.Project();
+      source.CopyToEntity(result);
+      return result;
+    }
+    public static void CopyToEntity(this DT.Project source, DA.Project target) {
+      if ((source == null) || (target == null)) return;
+      target.ProjectId = source.Id;
+      target.ParentProjectId = source.ParentProjectId;
+      target.DateCreated = source.DateCreated;
+      target.Name = source.Name;
+      target.Description = source.Description;
+      target.OwnerUserId = source.OwnerUserId;
+      target.StartDate = source.StartDate;
+      target.EndDate = source.EndDate;
+    }
+    #endregion
+
+    #region ProjectPermission
+    public static DT.ProjectPermission ToDto(this DA.ProjectPermission source) {
+      if (source == null) return null;
+      return new DT.ProjectPermission {
+        ProjectId = source.ProjectId,
         GrantedUserId = source.GrantedUserId,
         GrantedByUserId = source.GrantedByUserId
       };
     }
-    public static DA.ResourcePermission ToEntity(this DT.ResourcePermission source) {
-      if (source == null) return null;
-      var result = new DA.ResourcePermission();
-      source.CopyToEntity(result);
-      return result;
-    }
-    public static void CopyToEntity(this DT.ResourcePermission source, DA.ResourcePermission target) {
-      if ((source == null) || (target == null)) return;
-      target.ResourceId = source.ResourceId;
+    public static DA.ProjectPermission ToEntity(this DT.ProjectPermission source) {
+      if (source == null) return null;
+      var result = new DA.ProjectPermission();
+      source.CopyToEntity(result);
+      return result;
+    }
+    public static void CopyToEntity(this DT.ProjectPermission source, DA.ProjectPermission target) {
+      if ((source == null) || (target == null)) return;
+      target.ProjectId = source.ProjectId;
       target.GrantedUserId = source.GrantedUserId;
       target.GrantedByUserId = source.GrantedByUserId;
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/DataTransfer/Project.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/DataTransfer/Project.cs	(revision 15379)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/DataTransfer/Project.cs	(revision 15379)
@@ -0,0 +1,42 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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;
+using System.Runtime.Serialization;
+
+namespace HeuristicLab.Services.Hive.DataTransfer {
+  [DataContract]
+  [Serializable]
+  public class Project : NamedHiveItem {
+    [DataMember]
+    public Guid? ParentProjectId { get; set; }
+    [DataMember]
+    public DateTime DateCreated { get; set; }
+    [DataMember]
+    public Guid OwnerUserId { get; set; }
+    [DataMember]
+    public DateTime StartDate { get; set; }
+    [DataMember]
+    public DateTime? EndDate { get; set; }
+
+    public Project() { }
+  }
+}
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/DataTransfer/ProjectPermission.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/DataTransfer/ProjectPermission.cs	(revision 15379)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/DataTransfer/ProjectPermission.cs	(revision 15379)
@@ -0,0 +1,39 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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;
+using System.Runtime.Serialization;
+
+namespace HeuristicLab.Services.Hive.DataTransfer {
+  [DataContract]
+  [Serializable]
+  public class ProjectPermission : HiveItem {
+    // info: this class is derived from HiveItem to simplify handling on the client side, altough it does not have a Id.
+    [DataMember]
+    public Guid ProjectId { get; set; }
+    [DataMember]
+    public Guid GrantedUserId { get; set; }
+    [DataMember]
+    public Guid GrantedByUserId { get; set; }
+
+    public ProjectPermission() { }
+  }
+}
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/DataTransfer/ResourcePermission.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/DataTransfer/ResourcePermission.cs	(revision 15378)
+++ 	(revision )
@@ -1,39 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 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;
-using System.Runtime.Serialization;
-
-namespace HeuristicLab.Services.Hive.DataTransfer {
-  [DataContract]
-  [Serializable]
-  public class ResourcePermission : HiveItem {
-    // info: this class is derived from HiveItem to simplify handling on the client side, altough it does not have a Id.
-    [DataMember]
-    public Guid ResourceId { get; set; }
-    [DataMember]
-    public Guid GrantedUserId { get; set; }
-    [DataMember]
-    public Guid GrantedByUserId { get; set; }
-
-    public ResourcePermission() { }
-  }
-}
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj	(revision 15378)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj	(revision 15379)
@@ -120,6 +120,7 @@
     <Compile Include="Converter.cs" />
     <Compile Include="DataTransfer\Command.cs" />
+    <Compile Include="DataTransfer\Project.cs" />
+    <Compile Include="DataTransfer\ProjectPermission.cs" />
     <Compile Include="DataTransfer\UserPriority.cs" />
-    <Compile Include="DataTransfer\ResourcePermission.cs" />
     <Compile Include="DataTransfer\Downtime.cs" />
     <Compile Include="DataTransfer\Heartbeat.cs" />
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 15378)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 15379)
@@ -532,6 +532,5 @@
           result = HeartbeatManager.ProcessHeartbeat(heartbeat);
         }
-      }
-      catch (Exception ex) {
+      } catch (Exception ex) {
         DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
       }
@@ -604,15 +603,93 @@
     #endregion
 
-    #region ResourcePermission Methods
-    public void GrantResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
-      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      var pm = PersistenceManager;
-      using (new PerformanceLogger("GrantResourcePermissions")) {
-        pm.UseTransaction(() => {
-          var resource = AuthorizeForResource(pm, resourceId);
-          var resourcePermissions = resource.ResourcePermissions.ToList();
+    #region Project Methods
+    public Guid AddProject(DT.Project projectDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("AddProject")) {
+        var projectDao = pm.ProjectDao;
+        return pm.UseTransaction(() => {
+          var project = projectDao.Save(projectDto.ToEntity());
+          pm.SubmitChanges();
+          return project.ProjectId;
+        });
+      }
+    }
+
+    public void UpdateProject(DT.Project projectDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("UpdateProject")) {
+        var projectDao = pm.ProjectDao;
+        pm.UseTransaction(() => {
+          var project = projectDao.GetById(projectDto.Id);
+          if (project != null) {
+            projectDto.CopyToEntity(project);
+          } else {
+            projectDao.Save(projectDto.ToEntity());
+          }
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public void DeleteProject(Guid projectId) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      AuthorizationManager.AuthorizeForResourceAdministration(projectId);
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("DeleteProject")) {
+        var projectDao = pm.ProjectDao;
+        pm.UseTransaction(() => {
+          projectDao.Delete(projectId);
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public DT.Project GetProject(Guid projectId) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("GetProject")) {
+        var projectDao = pm.ProjectDao;
+        return pm.UseTransaction(() => projectDao.GetById(projectId).ToDto());
+      }
+    }
+
+    public IEnumerable<DT.Project> GetProjects() {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("GetProjects")) {
+        var projectDao = pm.ProjectDao;
+        var projectPermissionDao = pm.ProjectPermissionDao;
+        var currentUserId = UserManager.CurrentUserId;
+        return pm.UseTransaction(() => {
+          var resourcePermissions = projectPermissionDao.GetAll();
+          return projectDao.GetAll().ToList()
+            .Where(x => isAdministrator
+              || x.OwnerUserId == currentUserId
+              || UserManager.VerifyUser(currentUserId, resourcePermissions
+                  .Where(y => y.ProjectId == x.ProjectId)
+                  .Select(z => z.GrantedUserId)
+                  .ToList())
+              )
+            .Select(x => x.ToDto())
+            .ToList();
+        });
+      }
+    }
+    #endregion
+
+    #region ProjectPermission Methods
+    public void GrantProjectPermissions(Guid projectId, Guid[] grantedUserIds) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("GrantProjectPermissions")) {
+        pm.UseTransaction(() => {
+          var project = AuthorizeForProject(pm, projectId);
+          var projectPermissions = project.ProjectPermissions.ToList();
           foreach (var id in grantedUserIds) {
-            if (resourcePermissions.All(x => x.GrantedUserId != id)) {
-              resource.ResourcePermissions.Add(new DA.ResourcePermission {
+            if (projectPermissions.All(x => x.GrantedUserId != id)) {
+              project.ProjectPermissions.Add(new DA.ProjectPermission {
                 GrantedUserId = id,
                 GrantedByUserId = UserManager.CurrentUserId
@@ -625,23 +702,23 @@
     }
 
-    public void RevokeResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
-      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      var pm = PersistenceManager;
-      using (new PerformanceLogger("RevokeResourcePermissions")) {
-        var resourcePermissionDao = pm.ResourcePermissionDao;
-        pm.UseTransaction(() => {
-          AuthorizeForResource(pm, resourceId);
-          resourcePermissionDao.DeleteByResourceAndGrantedUserId(resourceId, grantedUserIds);
-          pm.SubmitChanges();
-        });
-      }
-    }
-
-    public IEnumerable<DT.ResourcePermission> GetResourcePermissions(Guid resourceId) {
-      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      var pm = PersistenceManager;
-      using (new PerformanceLogger("GetResourcePermissions")) {
-        var resourcePermissionDao = pm.ResourcePermissionDao;
-        return pm.UseTransaction(() => resourcePermissionDao.GetByResourceId(resourceId)
+    public void RevokeProjectPermissions(Guid projectId, Guid[] grantedUserIds) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("RevokeProjectPermissions")) {
+        var projectPermissionDao = pm.ProjectPermissionDao;
+        pm.UseTransaction(() => {
+          AuthorizeForProject(pm, projectId);
+          projectPermissionDao.DeleteByProjectAndGrantedUserId(projectId, grantedUserIds);
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public IEnumerable<DT.ProjectPermission> GetProjectPermissions(Guid projectId) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("GetProjectPermissions")) {
+        var projectPermissionDao = pm.ProjectPermissionDao;
+        return pm.UseTransaction(() => projectPermissionDao.GetByProjectId(projectId)
           .Select(x => x.ToDto())
           .ToList()
@@ -696,5 +773,5 @@
       using (new PerformanceLogger("GetSlaves")) {
         var slaveDao = pm.SlaveDao;
-        var resourcePermissionDao = pm.ResourcePermissionDao;
+        var resourcePermissionDao = pm.ProjectPermissionDao;
         var currentUserId = UserManager.CurrentUserId;
         return pm.UseTransaction(() => {
@@ -721,5 +798,5 @@
       using (new PerformanceLogger("GetSlaveGroups")) {
         var slaveGroupDao = pm.SlaveGroupDao;
-        var resourcePermissionDao = pm.ResourcePermissionDao;
+        var resourcePermissionDao = pm.ProjectPermissionDao;
         var currentUserId = UserManager.CurrentUserId;
         return pm.UseTransaction(() => {
@@ -990,13 +1067,13 @@
     }
 
-    private DA.Resource AuthorizeForResource(IPersistenceManager pm, Guid resourceId) {
-      var resourceDao = pm.ResourceDao;
-      var resource = resourceDao.GetById(resourceId);
-      if (resource == null) throw new SecurityException("Not authorized");
-      if (resource.OwnerUserId != UserManager.CurrentUserId
+    private DA.Project AuthorizeForProject(IPersistenceManager pm, Guid projectId) {
+      var projectDao = pm.ProjectDao;
+      var project = projectDao.GetById(projectId);
+      if (project == null) throw new SecurityException("Not authorized");
+      if (project.OwnerUserId != UserManager.CurrentUserId
           && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
         throw new SecurityException("Not authorized");
       }
-      return resource;
+      return project;
     }
     #endregion
Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/ServiceContracts/IHiveService.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/ServiceContracts/IHiveService.cs	(revision 15378)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/ServiceContracts/IHiveService.cs	(revision 15379)
@@ -132,4 +132,21 @@
     #endregion
 
+    #region Project Methods
+    [OperationContract]
+    Guid AddProject(Project projectDto);
+
+    [OperationContract]
+    void UpdateProject(Project projectDto);
+
+    [OperationContract]
+    void DeleteProject(Guid projectId);
+
+    [OperationContract]
+    Project GetProject(Guid projectId);
+
+    [OperationContract]
+    IEnumerable<Project> GetProjects();
+    #endregion
+
     #region ResourcePermission Methods
     [OperationContract]
@@ -140,5 +157,5 @@
 
     [OperationContract]
-    IEnumerable<ResourcePermission> GetResourcePermissions(Guid resourceId);
+    IEnumerable<ProjectPermission> GetResourcePermissions(Guid resourceId);
     #endregion
 
