public Maybe<QueryPlan> Build(QueryData data, DocumentIndexTypeToken projectContextType, DocumentIndexTypeToken _, DocumentIndexTypeToken __)
		{
			var query = _indexDataFactory.CreateImpedimentData(false, data.LoggedUserId, data.LoggedUserId);
			IDocumentIndex impedimentContextIndex = _documentIndexProvider.GetOrCreateDocumentIndex(_pluginContext, DocumentIndexTypeToken.Impediment);
			var impedimentPlan = impedimentContextIndex.BuildExecutionPlan(new ParsedQuery(words: query), _profile.Initialized);
			var projectContextPlan = _plansBuilder.BuildProjectContextPlan(data.ProjectIds, data.IncludeNoProject, projectContextType);
			return projectContextPlan.And(Maybe.Return(impedimentPlan));
		}
		public Maybe<Lazy<WAHBitArray>> Build(QueryData data, DocumentIndexTypeToken projectContextType, DocumentIndexTypeToken squadContextType, DocumentIndexTypeToken entityType)
		{
			var projectContextPlan = BuildProjectContextPlan(data.ProjectIds, data.IncludeNoProject, projectContextType);
			var squadPlan = BuildSquadPlan(data.TeamIds, data.IncludeNoTeam, squadContextType);
			var projectAndSquad = Op(projectContextPlan, squadPlan, Operation.And);
			var noSquadEntityPlan = BuildNoSquadEntityProjectContextPlan(data, projectContextType, entityType);
			var resultPlan = Op(projectAndSquad, noSquadEntityPlan, Operation.Or);
			var projectsReachableThroughTeamsPlan = BuildProjectReachableThroughTeamContextPlan(data, projectContextType, squadContextType);
			return Op(resultPlan, projectsReachableThroughTeamsPlan, Operation.Or);
		}
		public QueryPlan Build(QueryData data, string query)
		{
			Maybe<Lazy<WAHBitArray>> entityPlan = CreateEntityPlan(data, query);
			Maybe<Lazy<WAHBitArray>> commentPlan = CreateCommentPlan(data, query);
			return new QueryPlan
				{
					EntityPlan = entityPlan,
					CommentPlan = commentPlan
				};
		}
		public QueryResult Run(QueryData data)
		{
			if (string.IsNullOrEmpty(data.Query))
			{
				return new QueryResult();
			}
			string parsedQuery = _queryParser.Parse(data.Query);
			QueryPlan queryPlan = _queryPlanBuilder.Build(data, parsedQuery);
			QueryRunResult result = _queryPlanExecutor.Run(queryPlan, Map(data.Page));
			return CreateResult(result, data);
		}
 public QueryPlanFull Build(QueryData data, ParsedQuery parsedQuery)
 {
     Maybe<QueryPlan> entityPlan = CreateEntityPlan(data, parsedQuery);
     Maybe<QueryPlan> commentPlan = CreateCommentPlan(data, parsedQuery);
     return new QueryPlanFull
         {
             Query = parsedQuery,
             EntityPlan = entityPlan,
             CommentPlan = commentPlan
         };
 }
 public QueryResult Run(QueryData data)
 {
     if (string.IsNullOrEmpty(data.Query))
     {
         return new QueryResult();
     }
     var parsedQuery = _queryParser.Parse(data.Query);
     QueryPlanFull queryPlanFull = _queryPlanBuilder.Build(data, parsedQuery);
     QueryRunResult result = _queryEngine.Run(queryPlanFull, Map(data.Page));
     return CreateResult(result, data);
 }
		public bool ShouldBuild(QueryData data)
		{
			if (data.LoggedUserId == null)
			{
				return false;
			}
			if(data.EntityTypeId == null)
			{
				return true;
			}
			return _entityTypeProvider.IsImpediment(data.EntityTypeId);
		}
		private Maybe<Lazy<WAHBitArray>> CreateCommentPlan(QueryData data, string query)
		{
			if (!data.ShouldSearchComment)
			{
				return Maybe.Nothing;
			}
			var contextPlan = _contextQueryPlanBuilder.Build(data, DocumentIndexTypeToken.CommentProject, DocumentIndexTypeToken.CommentSquad, DocumentIndexTypeToken.CommentEntityType);
			if (!contextPlan.HasValue)
			{
				return Maybe.Nothing;
			}
			var commentIndex = _documentIndexProvider.GetOrCreateDocumentIndex(_accountName, DocumentIndexTypeToken.Comment);
			var plan = commentIndex.BuildExecutionPlan(query, _profile.Initialized);
			return And(plan, contextPlan);
		}
		private Maybe<QueryPlan> CreateTestStepPlan(QueryData data, ParsedQuery parsedQuery)
		{
			if (!data.ShouldSearchTestStep)
			{
				return Maybe.Nothing;
			}
			var projectContextPlan = _contextQueryPlanBuilder.BuildProjectContextPlan(data.ProjectIds, data.IncludeNoProject, DocumentIndexTypeToken.TestStepProject);
			if (!projectContextPlan.HasValue)
			{
				return Maybe.Nothing;
			}
			var commentIndex = _documentIndexProvider.GetOrCreateDocumentIndex(_pluginContext, DocumentIndexTypeToken.TestStep);
			var plan = commentIndex.BuildExecutionPlan(parsedQuery, _profile.Initialized);
			return And(plan, projectContextPlan);
		}
 private Maybe<QueryPlan> CreateCommentPlan(QueryData data, ParsedQuery parsedQuery)
 {
     if (!data.ShouldSearchComment)
     {
         return Maybe.Nothing;
     }
     var contextPlan = _contextQueryPlanBuilder.Build(data, DocumentIndexTypeToken.CommentProject, DocumentIndexTypeToken.CommentSquad, DocumentIndexTypeToken.CommentEntityType);
     if (!contextPlan.HasValue)
     {
         return Maybe.Nothing;
     }
     var commentIndex = _documentIndexProvider.GetOrCreateDocumentIndex(_pluginContext, DocumentIndexTypeToken.Comment);
     var plan = commentIndex.BuildExecutionPlan(parsedQuery, _profile.Initialized);
     return And(plan, contextPlan);
 }
		private Maybe<QueryPlan> BuildProjectReachableThroughTeamContextPlan(QueryData data, DocumentIndexTypeToken projectContextType, DocumentIndexTypeToken squadContextType)
		{
			if (data.TeamProjectRelations == null)
			{
				return Maybe.Nothing;
			}
			Maybe<QueryPlan> result = Maybe.Nothing;
			foreach (var projectsReachableThroughTeamData in data.TeamProjectRelations)
			{
				var projectContextPlan = BuildProjectContextPlan(projectsReachableThroughTeamData.ProjectIds, false, projectContextType);
				var squadPlan = BuildSquadPlan(new[] { projectsReachableThroughTeamData.TeamId }, false, squadContextType);
				var temp = projectContextPlan.And(squadPlan);
				result = result.Or(temp);
			}
			return result;
		}
		private Maybe<Lazy<WAHBitArray>> BuildProjectReachableThroughTeamContextPlan(QueryData data, DocumentIndexTypeToken projectContextType, DocumentIndexTypeToken squadContextType)
		{
			if (data.TeamProjectRelations == null)
			{
				return Maybe.Nothing;
			}
			Maybe<Lazy<WAHBitArray>> result = Maybe.Nothing;
			foreach (var projectsReachableThroughTeamData in data.TeamProjectRelations)
			{
				var projectContextPlan = BuildProjectContextPlan(projectsReachableThroughTeamData.ProjectIds, false, projectContextType);
				var squadPlan = BuildSquadPlan(new[] { projectsReachableThroughTeamData.TeamId }, false, squadContextType);
				var temp = Op(projectContextPlan, squadPlan, Operation.And);
				result = Op(result, temp, Operation.Or);
			}
			return result;
		}
		public Maybe<QueryPlan> Build(QueryData data, DocumentIndexTypeToken projectContextType, DocumentIndexTypeToken squadContextType, DocumentIndexTypeToken entityType)
		{
			var projectContextPlan = BuildProjectContextPlan(data.ProjectIds, data.IncludeNoProject, projectContextType);
			var squadPlan = BuildSquadPlan(data.TeamIds, data.IncludeNoTeam, squadContextType);
			var projectAndSquad = projectContextPlan.And(squadPlan);
			var noSquadEntityPlan = BuildNoSquadEntityProjectContextPlan(data, projectContextType, entityType);
			var resultPlan = projectAndSquad.Or(noSquadEntityPlan);
			var projectsReachableThroughTeamsPlan = BuildProjectReachableThroughTeamContextPlan(data, projectContextType, squadContextType);
			resultPlan = resultPlan.Or(projectsReachableThroughTeamsPlan);
			resultPlan = _planBuilders.Where(b => b.ShouldBuild(data)).Aggregate(resultPlan, (acc, builder) =>
				{
					var plan = builder.Build(data, projectContextType, squadContextType, entityType);
					return acc.Or(plan);
				});
			return resultPlan;
		}
		private QueryResult CreateResult(QueryRunResult queryResult, QueryData queryData)
		{
			QueryEntityTypeProvider.SearchResult result = _queryResultFactory.CreateQueryResult(queryResult.Entities);
			var searchResult = new QueryResult
				{
					GeneralIds = result.GeneralIds.ToArray(),
					AssignableIds = result.AssignableIds.ToArray(),
					TestCaseIds = result.TestCaseIds.ToArray(),
					CommentIds = queryResult.Comments.Select(i => i.FileName).ToArray(),
					QueryString = queryData.Query,
					Total = queryResult.EntitiesTotalCount + queryResult.CommentsTotalCount,
					LastIndexedEntityId = queryResult.LastIndexedEntityId,
					LastIndexedCommentId = queryResult.LastIndexedCommentId
				};
			return searchResult;
		}
 private Maybe<QueryPlan> CreateEntityPlan(QueryData queryData, ParsedQuery parsedQuery)
 {
     if (queryData.IsCommentEntityType)
     {
         return Maybe.Nothing;
     }
     var contextPlan = _contextQueryPlanBuilder.Build(queryData, DocumentIndexTypeToken.EntityProject, DocumentIndexTypeToken.EntitySquad, DocumentIndexTypeToken.EntityType);
     if (!contextPlan.HasValue)
     {
         return Maybe.Nothing;
     }
     QueryPlan plan = CreateEntityQueryPlan(parsedQuery);
     plan = And(plan, CreateEntityTypePlan(queryData.EntityTypeId));
     plan = And(plan, CreateEntityStatePlan(queryData.EntityStateIds));
     plan = And(plan, contextPlan);
     return plan;
 }
		private Maybe<Lazy<WAHBitArray>> BuildNoSquadEntityProjectContextPlan(QueryData data, DocumentIndexTypeToken project, DocumentIndexTypeToken entityType)
		{
			var projectContextPlan = BuildProjectContextPlan(data.ProjectIds, data.IncludeNoProject, project);
			if (!projectContextPlan.HasValue)
			{
				return Maybe.Nothing;
			}
			string noSquadEntityTypeIdsQuery = String.Join(" ", _entityTypeProvider.NoSquadEntityTypeNames);
			IDocumentIndex entityTypeIndex = _documentIndexProvider.GetOrCreateDocumentIndex(_accountName, entityType);
			Lazy<WAHBitArray> noSquadEntityPlan = entityTypeIndex.BuildExecutionPlan(noSquadEntityTypeIdsQuery, _profile.Initialized);
			return Maybe.Return(Lazy.Create(() => noSquadEntityPlan.Value.And(projectContextPlan.Value.Value)));
		}
		public void ShouldNotFindTestStepAfterIndexIsRemoved()
		{
			var indexer = GetInstance<IEntityIndexer>();
			const int testCaseTypeId = QueryEntityTypeProvider.TESTCASE_TYPE_ID;
			indexer.AddGeneralIndex(new GeneralDTO
			{
				ID = 1,
				Name = "Searchable Test Case Name",
				EntityTypeID = testCaseTypeId,
				ParentProjectID = 1
			});
			indexer.AddTestStepIndex(new TestStepDTO
			{
				ID = 1,
				Description = "Searchable Test Step Description",
				Result = "Searchable Test Step Result",
				TestCaseID = 1
			});
			var queryRunner = GetInstance<QueryRunner>();
			var queryData = new QueryData
			{
				Query = "Searchable Test Step",
				ProjectIds = new[] {1},
				EntityTypeId = testCaseTypeId
			};
			var result = queryRunner.Run(queryData);
			result.Total.Should(Be.EqualTo(1), "result.Total.Should(Be.EqualTo(1))");
			result.TestStepIds.Should(Be.EquivalentTo(new[] { 1 }.Select(x => x.ToString(CultureInfo.InvariantCulture))), "result.TestStepIds.Should(Be.EquivalentTo(new[] { 1 }.Select(x => x.ToString(CultureInfo.InvariantCulture))))");
			indexer.RemoveTestStepIndex(new TestStepDTO
			{
				ID = 1,
				TestCaseID = 1
			});
			var resultAfterRemove = queryRunner.Run(queryData);
			resultAfterRemove.Total.Should(Be.EqualTo(0), "resultAfterRemove.Total.Should(Be.EqualTo(0))");
		}
		private Maybe<QueryPlan> BuildNoSquadEntityProjectContextPlan(QueryData data, DocumentIndexTypeToken project, DocumentIndexTypeToken entityType)
		{
			var projectContextPlan = BuildProjectContextPlan(data.ProjectIds, data.IncludeNoProject, project);
			if (!projectContextPlan.HasValue)
			{
				return Maybe.Nothing;
			}
			string noSquadEntityTypeIdsQuery = String.Join(" ", _entityTypeProvider.NoSquadEntityTypeNames);
			IDocumentIndex entityTypeIndex = _documentIndexProvider.GetOrCreateDocumentIndex(_pluginContext, entityType);
			QueryPlan noSquadEntityPlan = entityTypeIndex.BuildExecutionPlan(new ParsedQuery(words:noSquadEntityTypeIdsQuery), _profile.Initialized);
			return Maybe.Return(QueryPlan.And(noSquadEntityPlan, projectContextPlan.Value));
		}