public virtual void Index(string scope, string documentType, IDocument document)
        {
            var core = GetCoreName(scope, documentType);
            if (!_pendingDocuments.ContainsKey(core))
            {
                _pendingDocuments.Add(core, new List<ESDocument>());
            }

            string mapping = null;
            if (!_mappings.ContainsKey(core))
            {
                // Get mapping info
                if (Client.IndexExists(new IndexExistsCommand(scope)))
                {
                    mapping = GetMappingFromServer(scope, documentType, core);
                }
            }
            else
            {
                mapping = _mappings[core];
            }

            var submitMapping = false;

            var properties = new Properties<ESDocument>();
            var localDocument = new ESDocument();

            for (var index = 0; index < document.FieldCount; index++)
            {
                var field = document[index];

                var key = field.Name.ToLower();

                if (localDocument.ContainsKey(key))
                {
                    var objTemp = localDocument[key];
                    object[] objListTemp;
                    var temp = objTemp as object[];
                    if (temp != null)
                    {
                        var objList = new List<object>(temp) { field.Value };
                        objListTemp = objList.ToArray();
                    }
                    else
                    {
                        objListTemp = new[] { objTemp, field.Value };
                    }

                    localDocument[key] = objListTemp;
                }
                else
                {
                    if (String.IsNullOrEmpty(mapping) || !mapping.Contains(String.Format("\"{0}\"", field.Name)))
                    {
                        var type = field.Value != null ? field.Value.GetType() : null;
                        var propertyMap = new CustomPropertyMap<ESDocument>(field.Name, type)
                        .Store(field.ContainsAttribute(IndexStore.Yes))
                        .When(field.ContainsAttribute(IndexType.NotAnalyzed), p => p.Index(IndexState.not_analyzed))
                        .When(field.Name.StartsWith("__content", StringComparison.OrdinalIgnoreCase), p => p.Analyzer(SearchAnalyzer))
                        .When(Regex.Match(field.Name, "__content_en.*").Success, x => x.Analyzer("english"))
                        .When(Regex.Match(field.Name, "__content_de.*").Success, x => x.Analyzer("german"))
                        .When(Regex.Match(field.Name, "__content_ru.*").Success, x => x.Analyzer("russian"))
                        .When(field.ContainsAttribute(IndexType.No), p => p.Index(IndexState.no));

                        properties.CustomProperty(field.Name, p => propertyMap);

                        submitMapping = true;
                    }

                    localDocument.Add(key, field.Value);
                }
            }

            // submit mapping
            if (submitMapping)
            {
                //Use ngrams analyzer for search in the middle of word
                //http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/ngrams-compound-words.html
                var settings = new IndexSettingsBuilder()
                    .Analysis(als => als
                        .Analyzer(a => a.Custom(SearchAnalyzer, custom => custom
                            .Tokenizer(DefaultTokenizers.standard)
                            .Filter("trigrams_filter", DefaultTokenFilters.lowercase.ToString())))
                        .Filter(f => f.NGram("trigrams_filter", ng => ng
                                .MinGram(3)
                                .MaxGram(3)))).Build();

                if (!Client.IndexExists(new IndexExistsCommand(scope)))
                {
                    var response = Client.CreateIndex(new IndexCommand(scope), settings);
                    _settingsUpdated = true;
                    if (response.error != null)
                        throw new IndexBuildException(response.error);
                }
                else if (!_settingsUpdated)
                {
                    // We can't update settings on active index.
                    // So we need to close it, then update settings and then open index back.
                    Client.Close(new CloseCommand(scope));
                    Client.UpdateSettings(new UpdateSettingsCommand(scope), settings);
                    Client.Open(new OpenCommand(scope));
                    _settingsUpdated = true;
                }

                var mapBuilder = new MapBuilder<ESDocument>();
                var mappingNew = mapBuilder.RootObject(documentType, d => d.Properties(p => properties)).Build();

                var result = Client.PutMapping(new PutMappingCommand(scope, documentType), mappingNew);
                if (!result.acknowledged && result.error != null)
                    throw new IndexBuildException(result.error);

                GetMappingFromServer(scope, documentType, core);
            }

            _pendingDocuments[core].Add(localDocument);

            // Auto commit changes when limit is reached
            if (AutoCommit && _pendingDocuments[core].Count > AutoCommitCount)
            {
                Commit(scope);
            }
        }
        public virtual void Index(string scope, string documentType, IDocument document)
        {
            var core = GetCoreName(scope, documentType);
            if (!_pendingDocuments.ContainsKey(core))
            {
                _pendingDocuments.Add(core, new List<ESDocument>());
            }

            string mapping = null;
            if (!_mappings.ContainsKey(core))
            {
                // Get mapping info
                if (Client.IndexExists(new IndexExistsCommand(scope)))
                {
                    try
                    {
                        mapping = Client.GetMapping(new GetMappingCommand(scope, documentType));
                    }
                    catch (OperationException ex)
                    {
                        if (ex.HttpStatusCode != 404 || !ex.Message.Contains("TypeMissingException"))
                        {
                            throw;
                        }
                    }

                    if (mapping != null)
                        _mappings.Add(core, mapping);
                }
            }
            else
            {
                mapping = _mappings[core];
            }

            var submitMapping = false;

            var properties = new Properties<ESDocument>();
            var localDocument = new ESDocument();

            for (var index = 0; index < document.FieldCount; index++)
            {
                var field = document[index];

                var key = field.Name.ToLower();

                if (localDocument.ContainsKey(key))
                {
                    var objTemp = localDocument[key];
                    object[] objListTemp;
                    var temp = objTemp as object[];
                    if (temp != null)
                    {
                        var objList = new List<object>(temp) { field.Value };
                        objListTemp = objList.ToArray();
                    }
                    else
                    {
                        objListTemp = new[] { objTemp, field.Value };
                    }

                    localDocument[key] = objListTemp;
                }
                else
                {
                    if (String.IsNullOrEmpty(mapping) || !mapping.Contains(String.Format("\"{0}\"", key)))
                    {
                        var type = field.Value != null ? field.Value.GetType() : null;
                        var propertyMap = new CustomPropertyMap<ESDocument>(field.Name, type)
                        .Store(field.ContainsAttribute(IndexStore.YES))
                        .When(field.ContainsAttribute(IndexType.NOT_ANALYZED), p => p.Index(IndexState.not_analyzed))
                        .When(field.ContainsAttribute(IndexType.NO), p => p.Index(IndexState.no));

                        properties.CustomProperty(field.Name, p => propertyMap);

                        submitMapping = true;
                    }

                    localDocument.Add(key, field.Value);
                }
            }

            // submit mapping
            if (submitMapping)
            {
                if (!Client.IndexExists(new IndexExistsCommand(scope)))
                {
                    var response = Client.CreateIndex(new IndexCommand(scope));
                    if (response.error != null)
                        throw new IndexBuildException(response.error);
                }

                var mapBuilder = new MapBuilder<ESDocument>();
                var mappingNew = mapBuilder.RootObject(documentType, d => d.Properties(p => properties)).Build();

                var result = Client.PutMapping(new PutMappingCommand(scope, documentType), mappingNew);
                if (!result.acknowledged && result.error != null)
                    throw new IndexBuildException(result.error);
            }

            _pendingDocuments[core].Add(localDocument);

            // Auto commit changes when limit is reached
            if (AutoCommit && _pendingDocuments[core].Count > AutoCommitCount)
            {
                Commit(scope);
            }
        }