Inheritance: ExtensibleObject
        public async Task<HttpResponseMessage> GetTags(string projectName)
        {
            var document = new ReadDocument();

            var collectionSelfUri = MakeUri<TagController>(c => c.GetTags(projectName));

            //root object
            var tagsCollection = new Collection { Version = "1.0", Href = collectionSelfUri };

            //partial rep of each tag
            var tags = await Context.ProjectTagSet.Where(t => t.ProjectName.Equals(projectName)).ToListAsync();
            foreach (var tag in tags)
            {
                var particularProjectUri = MakeUri<TagController>(c => c.GetTagByName(projectName, tag.TagName));
                var item = new Item { Href = particularProjectUri };
                item.Data.Add(new Data { Name = "name", Value = tag.TagName, Prompt = "name of tag" });
                tagsCollection.Items.Add(item);
            }

            //template to insert new project
            var template = tagsCollection.Template.Data;
            template.Add(new Data { Name = "name", Prompt = "name of tag" });
            template.Add(new Data { Name = "top_entity", Prompt = "name of project", Value = projectName });


            document.Collection = tagsCollection;
            return Request.SetupResponse<IReadDocument>(HttpStatusCode.OK, document, CollectionResourceMediatype);
        }
        public Document Build(IEnumerable<Friend> friends)
        {
            var document = new Document();
            var collection = new Collection { Version = "1.0", Href = new Uri("http://example.org/friends/") };
            document.Collection = collection;

            collection.Links.Add(new Link { Rel = "Feed", Href = new Uri("http://example.org/friends/rss") });

            foreach (var friend in friends)
            {
                var item = new Item { Href = new Uri("http://example.org/friends/" + friend.ShortName) };
                item.Data.Add(new Data { Name = "full-name", Value = friend.FullName, Prompt = "Full Name" });
                item.Data.Add(new Data { Name = "email", Value = friend.Email, Prompt = "Email" });
                item.Links.Add(new Link { Rel = "blog", Href = friend.Blog, Prompt = "Blog" });
                item.Links.Add(new Link { Rel = "avatar", Href = friend.Avatar, Prompt = "Avatar", Render = "Image" });
                collection.Items.Add(item);
            }

            var query = new Query { Rel = "search", Href = new Uri("http://example.org/friends/search"), Prompt = "Search" };
            query.Data.Add(new Data { Name = "name" });
            collection.Queries.Add(query);

            var data = collection.Template.Data;
            data.Add(new Data { Name = "name", Prompt = "Full Name" });
            data.Add(new Data { Name = "email", Prompt = "Email" });
            data.Add(new Data { Name = "blog", Prompt = "Blog" });
            data.Add(new Data { Name = "avatar", Prompt = "Avatar" });
            return document;
        }
        public async Task<HttpResponseMessage> GetProjects(int page = 0, string containsName = "")
        {
            var document = new ReadDocument();

            var collectionSelfUri = MakeUri<ProjectsController>(c => c.GetProjects(page, containsName));

            //root object
            var allProjectsCollection = new Collection {Version = "1.0", Href = collectionSelfUri};

            //partial representation of all the projects
            const string idProperty = "id", nameProperty = "name";
            var allProjectsFound = Context.Projects.Where(p => p.Name.Contains(containsName)).OrderBy(p => p.Name);
            var projectsConsidered = await allProjectsFound.Skip(PageSize*page).Take(PageSize).ToListAsync();
            foreach (var project in projectsConsidered)
            {
                var particularProjectUri = MakeUri<ProjectsController>(c => c.FindSingleProject(project.Name));
                var item = new Item {Href = particularProjectUri};
                item.Data.Add(new Data {Name = idProperty, Value = project.Id.ToString(), Prompt = "ID of project"});
                item.Data.Add(new Data {Name = nameProperty, Value = project.Name, Prompt = "name of project"});
                allProjectsCollection.Items.Add(item);
            }

            //template to insert new project
            var template = allProjectsCollection.Template.Data;
            template.Add(new Data {Name = Rels.Template.ProjectsPropertyName, Prompt = "name of project"});
            template.Add(new Data {Name = Rels.Template.ProjectsPropertyTags, Prompt = "Each Tag's name separated by a plus sign"});

            //queries para obter uma lista de projetos onde expression está contido no nome
            allProjectsCollection.Queries.Add(new Query
            {
                Href = MakeUri<ProjectsController>(c => c.GetProjects(page, "")),
                Rel = "search",
                Prompt = "Search for projects with a name that contains the given expression.",
                Data = new List<Data> { new Data { Name = Rels.Search.ContainsName, Prompt = "The keyword to look for inside the names of each project." } }
            });

            
            SetupPaginationLinks(allProjectsCollection, allProjectsFound.Count(), page, previousPageUri(page), nextPageUri(page));

            document.Collection = allProjectsCollection;
            return Request.SetupResponse<IReadDocument>(HttpStatusCode.OK, document, CollectionResourceMediatype);
        }
        public async Task<HttpResponseMessage> GetIssues(string projectName, string state = "", string containsName = "", int page = 0)
        {
            var document = new ReadDocument();
            var collectionSelfUri = MakeUri<IssuesController>(c => c.GetIssues(projectName, null, null, 0));

            //root object
            var allIssuesCollection = new Collection{ Version = "1.0", Href = collectionSelfUri };
            IOrderedQueryable<IssueModel> allIssuesFound = null;

            if (state.Length > 0)
            {
                allIssuesFound = Context.Issues.Where(i =>
                    //to handle queries over the collection
                    (state.Length > 0)
                        ? i.ProjectModel.Name.Equals(projectName) && i.State.Equals(state)
                        : i.ProjectModel.Name.Equals(projectName)
                    ).OrderBy(i => i.Id);
            }
            else
            {
                allIssuesFound = Context.Issues.Where(i =>
                    //to handle queries over the collection
                    (containsName.Length > 0)
                        ? i.ProjectModel.Name.Equals(projectName) && i.Title.Contains(containsName)
                        : i.ProjectModel.Name.Equals(projectName)
                    ).OrderBy(i => i.Id);
            }
            var allIssuesConsidered = await allIssuesFound.Skip(PageSize * page).Take(PageSize).ToListAsync();

            //items
            foreach (var issue in allIssuesConsidered)
            {
                var particularIssueUri = MakeUri<IssuesController>(c => c.GetSingleIssue(projectName, issue.Id));
                var item = new Item { Href = particularIssueUri };
                item.Data.Add(new Data { Name = "title", Value = issue.Title, Prompt = "title of issue" });
                item.Data.Add(new Data { Name = "state", Value = issue.State, Prompt = "state of issue" });
                allIssuesCollection.Items.Add(item);
            }

            //template
            var template = allIssuesCollection.Template.Data;
            template.Add(new Data { Name = "title", Prompt = "title of issue" });
            template.Add(new Data { Name = "state", Prompt = "state of issue" });
            template.Add(new Data { Name = "description", Prompt = "description of issue" });
            template.Add(new Data { Name = "tags", Prompt = "Each tag's name, if any, separated by a plus sign." });

            //queries para obter uma lista de issues com um determinado state (open ou close)
            allIssuesCollection.Queries.Add(new Query
            {
                Href = collectionSelfUri,
                Rel = Rels.Query.FilterQueryName,
                Prompt = "Search for issues with a certain state.",
                Data = new List<Data> { new Data { Name = "state", Prompt = "The state to look for."} }
            });
            //queries para procurar por um issue que contenha um determinado nome
            allIssuesCollection.Queries.Add(new Query
            {
                Href = MakeUri<IssuesController>(c => c.GetIssues(projectName, "", "", page)),
                Rel = Rels.Query.SearchQueryName,
                Prompt = "Search for issues that contains the given expression.",
                Data = new List<Data> { new Data { Name = Rels.Search.ContainsName, Prompt = "The keyword to look for inside the names of each issue." } }
            });

            SetupPaginationLinks(allIssuesCollection, Context.Issues.Count(), page, previousPageUri(projectName, state, containsName, page), 
                nextPageUri(projectName, state, containsName, page));

            document.Collection = allIssuesCollection;
            return Request.SetupResponse<IReadDocument>(HttpStatusCode.OK, document, CollectionResourceMediatype);
        }
    public async Task<HttpResponseMessage> GetComments(string projectName, int issueId, [FromUri] string before = "",
      [FromUri] string after = "")
    {
      DateTime? beforeDate = null;
      DateTime? afterDate = null;

      if (!string.IsNullOrEmpty(before) && !string.IsNullOrWhiteSpace(before))
      {
        beforeDate = ParseDate(before);
      }
      if (!string.IsNullOrEmpty(after) && !string.IsNullOrWhiteSpace(after))
      {
        afterDate = ParseDate(after);
      }


      var collectionSelfUri = MakeUri<CommentsController>(c => c.GetComments(projectName, issueId, null, null));
      //root object
      var allCommentsCollection = new Collection {Version = "1.0", Href = collectionSelfUri};

      //DbFunctions.TruncateTime(someDateTimeObj) é igual a "someDateTimeObj.Date" mas LINQ não deixa utilizar esta ultima.
      var allCommentsTmp = Context.Comments
        .Where(c => c.IssueModel.Id == issueId
                    && c.ProjectModel.Name.Equals(projectName));


      if (afterDate != null)
      {
        allCommentsTmp =
          allCommentsTmp.Where(c => DbFunctions.TruncateTime(c.CreationDate) > DbFunctions.TruncateTime(afterDate));
      }
      if (beforeDate != null)
      {
        allCommentsTmp =
          allCommentsTmp.Where(c => DbFunctions.TruncateTime(c.CreationDate) < DbFunctions.TruncateTime(beforeDate));
      }

      var allComments = await allCommentsTmp.ToListAsync();
      foreach (var com in allComments)
      {
        var particularCommentUri =
          MakeUri<CommentsController>(c => c.GetSingleComment(projectName, com.IssueModel.Id, com.Id));
        var item = new Item {Href = particularCommentUri};
        item.Data.Add(new Data
        {
          Name = "created_on",
          Value = com.CreationDate.ToString(CultureInfo.InvariantCulture),
          Prompt = "Creation date"
        });
        item.Data.Add(new Data {Name = "content", Value = com.Content, Prompt = "The message"});
        allCommentsCollection.Items.Add(item);
      }

      var template = allCommentsCollection.Template.Data;
      template.Add(new Data {Name = "Content", Prompt = "content of comment"});

      allCommentsCollection.Queries.Add(new Query
      {
        Href = collectionSelfUri,
        Rel = Rels.Query.SearchQueryName,
        Prompt = "Search for comments within a certain date range.",
        Data = new List<Data>
        {
          new Data {Name = Rels.Search.After, Prompt = "Comments created after the given date."},
          new Data {Name = Rels.Search.Before, Prompt = "Comments created before the given date."}
        }
      });

      var document = new ReadDocument {Collection = allCommentsCollection};
      return Request.SetupResponse<IReadDocument>(HttpStatusCode.OK, document, CollectionResourceMediatype);
    }
 public TestReadDocument()
 {
     _collection = new Collection();
     _collection.Href = new Uri("http://test.com");
 }
 public ReadDocument()
 {
     Collection = new Collection();
 }