anchor.diff:                              (writers.Settings.FieldsLookup, predicate, searchQuery, searchProfile, queryTypes)
           }
       
  -    let search (searchQuery : SearchQuery.Dto, queryTypes) (state : State.T) = 
  +    let search (searchQuery : SearchQuery.Dto, queryTypes) = 
           maybe { 
  -            let! (index, state, writers) = state.IndexFactory 
  -                                           |> LazyFactory.getAsTuple searchQuery.IndexName IndexService.indexNotFound
  +            let! writers = indexService.IsIndexOnline <| searchQuery.IndexName
               let! query = generateSearchQuery (writers, searchQuery, None, queryTypes)
               let! (results, recordsReturned, totalAvailable) = SearchDsl.searchDocumentSeq (writers, query, searchQuery)
               let searchResults = new SearchResults()
  
positive.code: namespace FlexSearch.Core
  
  open FlexLucene.Analysis
  open System
  open System.Collections.Concurrent
  open System.Collections.Generic
  
negative.code:     abstract AddDocumentQueue : document:Document.Dto -> unit
      abstract AddOrUpdateDocumentQueue : document:Document.Dto -> unit
  
  ///  Analyzer/Analysis related services
  type IAnalyzerService = 
      abstract GetAnalyzer : analyzerName:string -> Choice<Analyzer, Error>
      abstract GetAnalyzerInfo : analyzerName:string -> Choice<Analyzer.Dto, Error>
      abstract DeleteAnalyzer : analyzerName:string -> Choice<unit, Error>
      abstract UpdateAnalyzer : analyzer:Analyzer.Dto -> Choice<unit, Error>
      abstract GetAllAnalyzers : unit -> Analyzer.Dto []
      abstract Analyze : analyzerName:string * input:string -> Choice<string, Error>
  
  [<Sealed>]
  type AnalyzerService(threadSafeWriter : ThreadSafeFileWiter, ?testMode : bool) = 
      let testMode = defaultArg testMode true
      
      let path = 
          Constants.ConfFolder +/ "Analyzer"
          |> Directory.CreateDirectory
          |> fun x -> x.FullName
      
      let store = conDict<Analyzer.Dto * Analyzer>()
      
      let updateAnalyzer (analyzer : Analyzer.Dto) = 
          maybe { 
              do! analyzer.Validate()
              let! instance = Analyzer.build (analyzer)
              do! threadSafeWriter.WriteFile(path +/ analyzer.AnalyzerName, analyzer)
              do! store
                  |> tryUpdate (analyzer.AnalyzerName, (analyzer, instance))
                  |> boolToResult UnableToUpdateMemory
          }
      
      let loadAllAnalyzers() = 
          Directory.EnumerateFiles(path) |> Seq.iter (fun x -> 
                                                match threadSafeWriter.ReadFile<Analyzer.Dto>(x) with
                                                | Choice1Of2(dto) -> updateAnalyzer (dto) |> ignore
                                                | Choice2Of2(error) -> ())
      
      do 
          // Add prebuilt analyzers
          let standardAnalyzer = new Analyzer.Dto(AnalyzerName = "standard")
          let instance = new FlexLucene.Analysis.Standard.StandardAnalyzer() :> Analyzer
          store |> add ("standard", (standardAnalyzer, instance))
          store |> add ("keyword", (new Analyzer.Dto(AnalyzerName = "keyword"), CaseInsensitiveKeywordAnalyzer))
          if not testMode then loadAllAnalyzers()
      
      interface IAnalyzerService with
          
          /// Create or update an existing analyzer
          member __.UpdateAnalyzer(analyzer : Analyzer.Dto) = updateAnalyzer (analyzer)
          
          /// Delete an analyzer. This 
          member __.DeleteAnalyzer(analyzerName : string) = 
              maybe { 
                  match store.TryGetValue(analyzerName) with
                  | true, _ -> 
                      do! threadSafeWriter.DeleteFile(path +/ analyzerName)
                      do! store
                          |> tryRemove (analyzerName)
                          |> boolToResult UnableToUpdateMemory
                      return! ok()
                  | _ -> return! ok()
              }
          
          member __.Analyze(analyzerName : string, input : string) = failwith "Not implemented yet"
          member __.GetAllAnalyzers() = 
              store.Values.ToArray() 
              |> Array.fold (fun acc (x : Analyzer.Dto * Analyzer) -> Array.append [| (fst x) |] acc) Array.empty
          
          member __.GetAnalyzer(analyzerName : string) = 
              match store.TryGetValue(analyzerName) with
              | true, (_, instance) -> ok <| instance
              | _ -> fail <| AnalyzerNotFound(analyzerName)
          
          member __.GetAnalyzerInfo(analyzerName : string) = 
              match store.TryGetValue(analyzerName) with
              | true, (dto, _) -> ok <| dto
              | _ -> fail <| AnalyzerNotFound(analyzerName)
  
  [<Sealed>]
  type IndexService(threadSafeWriter : ThreadSafeFileWiter, analyzerService : IAnalyzerService, ?testMode : bool) = 
      let testMode = defaultArg testMode true
      
      /// State information related to all the indices present in the
      /// system. An index can exist but be offline. In that case there
      /// won't be any associated index writer
      let state = conDict<Index.Dto * IndexWriter.T option>()
      
      /// Store to save all the index related information to the physical
      /// medium
      let dtoStore = new DtoStore<Index.Dto>(threadSafeWriter)
      
      /// Returns IndexNotFound error
      let indexNotFound (indexName) = IndexNotFound <| indexName
      
      /// Check if the given index exists
      let indexExists (indexName) = 
          match state.TryGetValue(indexName) with
          | true, _ -> ok()
          | _ -> fail <| indexNotFound indexName
      
      /// Checks if a given index is online or not. If it is 
      /// online then return the index writer
      let indexOnline (indexName) = 
          match state.TryGetValue(indexName) with
          | true, (_, writerOption) -> 
              match writerOption with
              | Some(writer) -> 
                  match writer.State with
                  | IndexState.Online -> ok <| writer
                  | _ -> fail <| IndexShouldBeOnline indexName
              | None -> fail <| IndexShouldBeOnline indexName
          | _ -> fail <| indexNotFound indexName
      
      let indexState (indexName) = 
          match state.TryGetValue(indexName) with
          | true, (_, writerOption) -> 
              match writerOption with
              | Some(writer) -> ok <| (writer.State, Some(writer))
              | None -> ok <| (IndexState.Offline, None)
          | _ -> fail <| indexNotFound indexName
      
      /// Load a index
      let loadIndex (index : Index.Dto) = 
          maybe { 
              let! setting = IndexWriter.createIndexSetting (index, analyzerService.GetAnalyzer)
              if index.Online then 
                  let indexWriter = IndexWriter.create (setting)
                  state
                  |> tryUpdate (index.IndexName, (index, Some(indexWriter)))
                  |> ignore
              else 
                  state
                  |> tryUpdate (index.IndexName, (index, None))
                  |> ignore
          }
      
      /// Load all index from the store
      let loadAllIndex() = 
          dtoStore.GetItems()
          |> Seq.map (fun i -> Task.Run(fun _ -> loadIndex i |> ignore))
          |> Seq.toArray
          |> Task.WaitAll
      
      do 
          if not testMode then loadAllIndex()
      
      interface IIndexService with
          member __.IsIndexOnline(indexName : string) = indexOnline (indexName)
          
          member __.AddIndex(index : Index.Dto) = 
              maybe { 
                  do! index.Validate()
                  match indexExists index.IndexName with
                  | Choice1Of2(_) -> return! fail <| IndexAlreadyExists(index.IndexName)
                  | _ -> 
                      do! dtoStore.UpdateItem(index.IndexName, index)
                      do! loadIndex <| index
                      return CreateResponse(index.IndexName)
              }
          
          member __.CloseIndex(indexName : string) = 
              maybe { 
                  let! (indexState, indexWriter) = indexState indexName
                  match indexState with
                  | IndexState.Closing | IndexState.Offline -> return! fail <| IndexIsAlreadyOffline(indexName)
                  | _ -> 
                      let item = fst state.[indexName]
                      item.Online <- false
                      do! dtoStore.UpdateItem(indexName, item)
                      indexWriter.Value |> IndexWriter.close
                      state
                      |> tryUpdate (indexName, (item, None))
                      |> ignore
              }
          
          member __.OpenIndex(indexName : string) = 
              maybe { 
                  let! (indexState, indexWriter) = indexState indexName
                  match indexState with
                  | IndexState.Opening | IndexState.Online -> return! fail <| IndexIsAlreadyOnline(indexName)
                  | _ -> 
                      let item = fst state.[indexName]
                      item.Online <- true
                      do! dtoStore.UpdateItem(indexName, item)
                      do! loadIndex item
              }
          
          member __.Commit(indexName : string) = maybe { let! writer = indexOnline indexName
                                                         writer |> IndexWriter.commit }
          member __.Refresh(indexName : string) = maybe { let! writer = indexOnline indexName
                                                          writer |> IndexWriter.refresh }
          member __.GetRealtimeSearcher(indexName : string, shardNo : int) = 
              maybe { let! writer = indexOnline indexName
                      return writer |> IndexWriter.getRealTimeSearcher shardNo }
          member __.GetRealtimeSearchers(indexName : string) = maybe { let! writer = indexOnline indexName
                                                                       return writer |> IndexWriter.getRealTimeSearchers }
          member __.GetIndex(indexName : string) = dtoStore.GetItem(indexName)
          member __.IndexExists(indexName : string) = dtoStore.GetItem(indexName) |> resultToBool
          member __.IndexOnline(indexName : string) = indexOnline indexName |> resultToBool
          
          member __.GetIndexState(indexName : string) = 
              match indexState indexName with
              | Choice1Of2(state, _) -> ok <| state
              | Choice2Of2(error) -> fail <| error
          
          member __.DeleteIndex(indexName : string) = 
              maybe { 
                  let! (_, writerOption) = indexState indexName
                  match writerOption with
                  | Some(writer) -> writer |> IndexWriter.close
                  | None -> ()
                  state.TryRemove(indexName) |> ignore
                  do! dtoStore.DeleteItem(indexName)
                  delDir (DataFolder +/ indexName)
              }
          
          member __.GetAllIndex() = dtoStore.GetItems()
          member __.UpdateIndexFields(fields : Field.Dto []) = failwith "Not implemented yet"
  
  [<Sealed>]
  type SearchService(parser : IFlexParser, queryFactory : IFlexFactory<IFlexQuery>, indexService : IIndexService) = 
      
      let getSearchPredicate (writers : IndexWriter.T, search : SearchQuery.Dto, 
                              inputValues : Dictionary<string, string> option) = 
  