public ProductBacklogItem(TenantId tenantId, ProductId productId, BacklogItemId backlogItemId, int ordering)
 {
     this.TenantId = tenantId;
     this.ProductId = productId;
     this.BacklogItemId = backlogItemId;
     this.Ordering = ordering;
 }
        public ProductDiscussionInitiated(TenantId tenantId, ProductId productId, ProductDiscussion productDiscussion)
        {
            this.TenantId = tenantId;
            this.ProductId = productId;
            this.ProductDiscussion = productDiscussion;

            this.EventVersion = 1;
            this.OccurredOn = DateTime.Now;
        }
        public BacklogItemDiscussionRequested(TenantId tenantId, ProductId productId, BacklogItemId backlogItemId, bool isRequested)
        {
            this.TenantId = tenantId;
            this.ProductId = productId;
            this.BacklogItemId = backlogItemId;
            this.IsRequested = isRequested;

            this.EventVersion = 1;
            this.OccurredOn = DateTime.Now;
        }
        public Release(TenantId tenantId, ProductId productId, ReleaseId releaseId, string name, string description, DateTime begins, DateTime ends)
        {
            this.TenantId = tenantId;
            this.ProductId = productId;
            this.ReleaseId = releaseId;
            this.Name = name;
            this.Description = description;
            this.Begins = begins;
            this.Ends = ends;

            _backlogItems = new HashSet<ScheduledBacklogItem>();
        }
        public ProductDiscussionRequested(TenantId tenantId, ProductId productId, ProductOwnerId productOwnerId,
            string name, string description, bool requestingDiscussion)
        {
            this.TenantId = tenantId;
            this.ProductId = productId;
            this.ProductOwnerId = productOwnerId;
            this.Name = name;
            this.Description = description;
            this.RequestingDiscussion = requestingDiscussion;

            this.EventVersion = 1;
            this.OccurredOn = DateTime.Now;
        }
        public ProductCreated(TenantId tenantId, ProductId productId, ProductOwnerId productOwnerId, string name,
            string description, DiscussionAvailability availability)
        {
            this.TenantId = tenantId;
            this.ProductId = productId;
            this.ProductOwnerId = productOwnerId;
            this.Name = name;
            this.Description = description;
            this.Availability = availability;

            this.EventVersion = 1;
            this.OccurredOn = DateTime.Now;
        }
        public ProductReleaseScheduled(TenantId tenantId, ProductId productId, ReleaseId releaseId, string name,
            string description, DateTime starts, DateTime ends)
        {
            this.TenantId = tenantId;
            this.ProductId = productId;
            this.ReleaseId = releaseId;
            this.Name = name;
            this.Description = description;
            this.Starts = starts;
            this.Ends = ends;

            this.EventVersion = 1;
            this.OccurredOn = DateTime.Now;
        }
        public ProductBacklogItemPlanned(TenantId tenantId, ProductId productId, BacklogItemId backlogItemId,
            string summary, string category, BacklogItemType backlogItemType, StoryPoints storyPoints)
        {
            this.TenantId = tenantId;
            this.ProductId = productId;
            this.BacklogItemId = backlogItemId;
            this.Summary = summary;
            this.Category = category;
            this.BacklogItemType = backlogItemType;
            this.StoryPoints = storyPoints;

            this.EventVersion = 1;
            this.OccurredOn = DateTime.Now;
        }
        public ProductSprintScheduled(TenantId tenantId, ProductId productId, SprintId sprintId, string name,
            string goals, DateTime starts, DateTime ends)
        {
            this.TenantId = tenantId;
            this.ProductId = productId;
            this.SprintId = sprintId;
            this.Name = name;
            this.Goals = goals;
            this.Starts = starts;
            this.Ends = ends;

            this.EventVersion = 1;
            this.OccurredOn = DateTime.Now;
        }
        public Product(TenantId tenantId, ProductId productId, ProductOwnerId productOwnerId, string name,
            string description, DiscussionAvailability discussionAvailability)
        {
            this.TenantId = tenantId;
            this.ProductId = productId;
            this.ProductOwnerId = productOwnerId;
            this.Name = name;
            this.Description = description;
            this.Discussion = ProductDiscussion.FromAvailability(discussionAvailability);
            this.DiscussionInitiationId = null;

            this._backlogItems = new HashSet<ProductBacklogItem>();

            DomainEventPublisher.Instance.Publish(new ProductCreated(this.TenantId, this.ProductId, this.ProductOwnerId,
                this.Name, this.Description, this.Discussion.Availability));
        }
        public Sprint(TenantId tenantId, ProductId productId, SprintId sprintId, string name, string goals,
            DateTime begins, DateTime ends)
        {
            if(ends.Ticks<begins.Ticks) {
                throw new InvalidOperationException("Sprint must not end before it begins.");
            }
            this.TenantId = tenantId;
            this.ProductId = productId;
            this.SprintId = sprintId;
            this.Name = name;
            this.Goals = goals;
            this.Begins = begins;
            this.Ends = ends;

            _backlogItems = new HashSet<CommittedBacklogItem>();
        }
        public BacklogItem(TenantId tenantId, ProductId productId, BacklogItemId backlogItemId, string summary,
            string category, BacklogItemType type, BacklogItemStatus backlogItemStatus, StoryPoints storyPoints)
        {
            AssertionConcern.NotEmpty(summary, "The summary must be provided.");
            AssertionConcern.Length(summary, 100, "The summary must be 100 characters or less.");

            this.TenantId = tenantId;
            this.ProductId = productId;
            this.BacklogItemId = backlogItemId;
            this.Summary = summary;
            this.Category = category;
            this.Type = type;
            this.Status = backlogItemStatus;
            this.StoryPoints = storyPoints;

            this._tasks = new List<Task>();
        }