You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by hi...@apache.org on 2016/09/13 22:44:36 UTC

[48/61] [abbrv] incubator-geode git commit: GEODE-37 change package name from com.gemstone.gemfire (for ./geode-lucene/src/main/java/com/gemstone/gemfire)to org.apache.geode for(to ./geode-lucene/src/main/java/org/apache/geode)

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java
deleted file mode 100644
index e06f99e..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.repository.serializer;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.lucene.document.Document;
-
-import com.gemstone.gemfire.internal.logging.LogService;
-
-/**
- * A lucene serializer that handles a single class and can
- * map an instance of that class to a document using reflection.
- */
-class ReflectionLuceneSerializer implements LuceneSerializer {
-
-  private Field[] fields;
-
-  private static final Logger logger = LogService.getLogger();
-  
-  public ReflectionLuceneSerializer(Class<? extends Object> clazz,
-      String[] indexedFields) {
-    Set<String> fieldSet = new HashSet<String>();
-    fieldSet.addAll(Arrays.asList(indexedFields));
-
-    //Iterate through all declared fields and save them
-    //in a list if they are an indexed field and have the correct
-    //type.
-    ArrayList<Field> foundFields = new ArrayList<Field>();
-    while(clazz != Object.class) {
-      for(Field field : clazz.getDeclaredFields()) {
-        Class<?> type = field.getType();
-        if(fieldSet.contains(field.getName()) 
-            && SerializerUtil.isSupported(type)) {
-          field.setAccessible(true);
-          foundFields.add(field);
-        }
-      }
-      
-      clazz = clazz.getSuperclass();
-    }
-    
-    this.fields = foundFields.toArray(new Field[foundFields.size()]);
-  }
-
-  @Override
-  public void toDocument(Object value, Document doc) {
-    for(Field field: fields) {
-      try {
-        Object fieldValue = field.get(value);
-        if (fieldValue == null) {
-          continue;
-        }
-        SerializerUtil.addField(doc, field.getName(), fieldValue);
-      } catch (IllegalArgumentException | IllegalAccessException e) {
-        //TODO - what to do if we can't read a field?
-      }
-    }
-    if (logger.isDebugEnabled()) {
-      logger.debug("ReflectionLuceneSerializer.toDocument:"+doc);
-    }
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java
deleted file mode 100644
index 4d563c1..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.repository.serializer;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.DoublePoint;
-import org.apache.lucene.document.Field.Store;
-import org.apache.lucene.document.FloatPoint;
-import org.apache.lucene.document.IntPoint;
-import org.apache.lucene.document.LongPoint;
-import org.apache.lucene.document.StringField;
-import org.apache.lucene.document.TextField;
-import org.apache.lucene.index.IndexableField;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.util.BytesRef;
-
-import com.gemstone.gemfire.DataSerializer;
-import com.gemstone.gemfire.InternalGemFireError;
-import com.gemstone.gemfire.internal.util.BlobHelper;
-
-/**
- * Static utility functions for mapping objects to lucene documents
- */
-public class SerializerUtil {
-  private static final String KEY_FIELD = "_KEY";
-
-  private static final Set<Class> SUPPORTED_PRIMITIVE_TYPES;
-
-  static {
-    HashSet<Class> primitiveTypes = new HashSet<>();
-    primitiveTypes.add(String.class);
-    primitiveTypes.add(long.class);
-    primitiveTypes.add(int.class);
-    primitiveTypes.add(float.class);
-    primitiveTypes.add(double.class);
-    primitiveTypes.add(Long.class);
-    primitiveTypes.add(Integer.class);
-    primitiveTypes.add(Float.class);
-    primitiveTypes.add(Double.class);
-
-    SUPPORTED_PRIMITIVE_TYPES = Collections.unmodifiableSet(primitiveTypes);
-  }
-  
-  /**
-   * A small buffer for converting keys to byte[] arrays.
-   */
-  private static ThreadLocal<ByteArrayOutputStream> LOCAL_BUFFER = new ThreadLocal<ByteArrayOutputStream>() {
-    @Override
-    protected ByteArrayOutputStream initialValue() {
-      return new ByteArrayOutputStream();
-    }
-  };
-
-  private SerializerUtil() {
-  }
-  
-  /**
-   * Add a gemfire key to a document
-   */
-  public static void addKey(Object key, Document doc) {
-    if(key instanceof String) {
-      doc.add(new StringField(KEY_FIELD, (String) key, Store.YES));
-    } else {
-      doc.add(new StringField(KEY_FIELD, keyToBytes(key), Store.YES));
-    }
-  }
-
-  /**
-   * Add a field to the document.
-   * 
-   * @return true if the field was successfully added
-   */
-  public static boolean addField(Document doc, String field, Object fieldValue) {
-    Class<?> clazz = fieldValue.getClass();
-    if(clazz == String.class) {
-      doc.add(new TextField(field, (String)fieldValue, Store.NO));
-    } else if (clazz == Long.class) {
-      doc.add(new LongPoint(field, (Long) fieldValue));
-    } else if (clazz == Integer.class) {
-      doc.add(new IntPoint(field, (Integer) fieldValue));
-    } else if (clazz == Float.class) {
-      doc.add(new FloatPoint(field, (Float) fieldValue));
-    }  else if (clazz == Double.class) {
-        doc.add(new DoublePoint(field, (Double) fieldValue));
-    } else {
-      return false;
-    }
-    
-    return true;
-  }
-
-  /**
-   * Return true if a field type can be written to a lucene document.
-   */
-  public static boolean isSupported(Class<?> type) {
-    return SUPPORTED_PRIMITIVE_TYPES.contains(type);
-  }
-
-  public static Collection<Class> supportedPrimitiveTypes() {
-    return SUPPORTED_PRIMITIVE_TYPES;
-  }
-  
-  /**
-   * Extract the gemfire key from a lucene document
-   */
-  public static Object getKey(Document doc) {
-    IndexableField field = doc.getField(KEY_FIELD);
-    if(field.stringValue() != null) {
-      return field.stringValue();
-    } else {
-      return  keyFromBytes(field.binaryValue());
-    }
-  }
- 
-  /**
-   * Extract the gemfire key term from a lucene document
-   */
-  public static Term getKeyTerm(Document doc) {
-    IndexableField field = doc.getField(KEY_FIELD);
-    if(field.stringValue() != null) {
-      return new Term(KEY_FIELD, field.stringValue());
-    } else {
-      return new Term(KEY_FIELD, field.binaryValue());
-    }
-  }
-  
-  /**
-   * Convert a gemfire key into a key search term that can be used to
-   * update or delete the document associated with this key.
-   */
-  public static Term toKeyTerm(Object key) {
-    if(key instanceof String) {
-      return new Term(KEY_FIELD, (String) key);
-    } else {
-      return new Term(KEY_FIELD, keyToBytes(key));
-    }
-  }
-  
-  private static Object keyFromBytes(BytesRef bytes) {
-    try {
-      return BlobHelper.deserializeBlob(bytes.bytes);
-    } catch (ClassNotFoundException | IOException e) {
-      throw new InternalGemFireError(e);
-    }
-  }
-  
-  /**
-   * Convert a key to a byte array.
-   */
-  private static BytesRef keyToBytes(Object key)  {
-    ByteArrayOutputStream buffer = LOCAL_BUFFER.get();
-    
-    try {
-      DataOutputStream out = new DataOutputStream(buffer);
-      DataSerializer.writeObject(key, out);
-      out.flush();
-      BytesRef result = new BytesRef(buffer.toByteArray());
-      buffer.reset();
-      return result;
-    } catch (IOException e) {
-      throw new InternalGemFireError("Unable to serialize key", e);
-    }
-  }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java
deleted file mode 100644
index dca7737..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * Classes for converting gemfire objects into lucene documents.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.repository.serializer;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java
deleted file mode 100644
index 98233b0..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
-
-import java.util.*;
-
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
-import org.apache.lucene.analysis.standard.StandardAnalyzer;
-
-import com.gemstone.gemfire.cache.Cache;
-import com.gemstone.gemfire.cache.Region;
-import com.gemstone.gemfire.cache.lucene.LuceneIndex;
-import com.gemstone.gemfire.cache.lucene.LuceneService;
-import com.gemstone.gemfire.cache.lucene.LuceneServiceProvider;
-import com.gemstone.gemfire.cache.lucene.internal.LuceneServiceImpl;
-import com.gemstone.gemfire.internal.cache.extension.Extensible;
-import com.gemstone.gemfire.internal.cache.extension.Extension;
-import com.gemstone.gemfire.internal.cache.xmlcache.XmlGenerator;
-
-public class LuceneIndexCreation implements LuceneIndex, Extension<Region<?, ?>> {
-  private Region region;
-  private String name;
-  private Set<String> fieldNames = new LinkedHashSet<String>();
-  private Map<String, Analyzer> fieldAnalyzers;
-
-  
-  public void setRegion(Region region) {
-    this.region = region;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public void setFieldAnalyzers(
-      Map<String, Analyzer> fieldAnalyzers) {
-    this.fieldAnalyzers = fieldAnalyzers;
-  }
-  
-  @Override
-  public Map<String, Analyzer> getFieldAnalyzers() {
-    if (this.fieldAnalyzers == null) {
-      this.fieldAnalyzers = new HashMap<>();
-    }
-    return this.fieldAnalyzers;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public String[] getFieldNames() {
-    return fieldNames.toArray(new String[fieldNames.size()]);
-  }
-
-  @Override
-  public String getRegionPath() {
-    return region.getFullPath();
-  }
-
-  @Override
-  public XmlGenerator<Region<?, ?>> getXmlGenerator() {
-    return new LuceneIndexXmlGenerator(this);
-  }
-
-  @Override
-  public void beforeCreate(Extensible<Region<?, ?>> source, Cache cache) {
-    LuceneServiceImpl service = (LuceneServiceImpl) LuceneServiceProvider.get(cache);
-    Analyzer analyzer = this.fieldAnalyzers == null
-        ? new StandardAnalyzer()
-        : new PerFieldAnalyzerWrapper(new StandardAnalyzer(), this.fieldAnalyzers);
-    service.createIndex(getName(), getRegionPath(), analyzer, this.fieldAnalyzers, getFieldNames());
-  }
-
-  @Override
-  public void onCreate(Extensible<Region<?, ?>> source, Extensible<Region<?, ?>> target) {}
-
-  protected void addField(String name) {
-    this.fieldNames.add(name);
-  }
-
-  protected void addFieldAndAnalyzer(String name, Analyzer analyzer) {
-    this.fieldNames.add(name);
-    getFieldAnalyzers().put(name, analyzer);
-  }
-
-  public void addFieldNames(String[] fieldNames) {
-    this.fieldNames.addAll(Arrays.asList(fieldNames));
-  }
-
-  @Override
-  public boolean waitUntilFlushed(int maxWaitInMillisecond) {
-    return true;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java
deleted file mode 100644
index 37c9ca2..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
-
-import static com.gemstone.gemfire.cache.lucene.internal.xml.LuceneXmlConstants.*;
-
-import org.apache.lucene.analysis.Analyzer;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
-
-import com.gemstone.gemfire.cache.Region;
-import com.gemstone.gemfire.cache.lucene.LuceneIndex;
-import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator;
-import com.gemstone.gemfire.internal.cache.xmlcache.XmlGenerator;
-import com.gemstone.gemfire.internal.cache.xmlcache.XmlGeneratorUtils;
-
-public class LuceneIndexXmlGenerator implements XmlGenerator<Region<?, ?>> {
-  private final LuceneIndex index;
-
-  public LuceneIndexXmlGenerator(LuceneIndex index) {
-    this.index = index;
-  }
-
-  @Override
-  public String getNamspaceUri() {
-    return NAMESPACE;
-  }
-
-  @Override
-  public void generate(CacheXmlGenerator cacheXmlGenerator)
-      throws SAXException {
-    final ContentHandler handler = cacheXmlGenerator.getContentHandler();
-
-    handler.startPrefixMapping(PREFIX, NAMESPACE);
-
-    AttributesImpl attr = new AttributesImpl();
-    //TODO - should the type be xs:string ?
-    XmlGeneratorUtils.addAttribute(attr, NAME, index.getName());
-    XmlGeneratorUtils.startElement(handler, PREFIX, INDEX, attr);
-    for(String field : index.getFieldNames()) {
-      AttributesImpl fieldAttr = new AttributesImpl();
-      XmlGeneratorUtils.addAttribute(fieldAttr, NAME, field);
-      Analyzer analyzer = index.getFieldAnalyzers().get(field);
-      if (analyzer != null) {
-        XmlGeneratorUtils.addAttribute(fieldAttr, ANALYZER, analyzer.getClass().getName());
-      }
-      XmlGeneratorUtils.emptyElement(handler, PREFIX, FIELD, fieldAttr);
-    }
-    XmlGeneratorUtils.endElement(handler, PREFIX, INDEX);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java
deleted file mode 100644
index c449f47..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
-
-import org.xml.sax.SAXException;
-
-import com.gemstone.gemfire.cache.Cache;
-import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator;
-import com.gemstone.gemfire.internal.cache.xmlcache.XmlGenerator;
-
-public final class LuceneServiceXmlGenerator implements XmlGenerator<Cache> {
-  @Override
-  public String getNamspaceUri() {
-    return LuceneXmlConstants.NAMESPACE;
-  }
-
-  @Override
-  public void generate(CacheXmlGenerator cacheXmlGenerator)
-      throws SAXException {
-    //Nothing to to the xml at the service level at the moment.
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java
deleted file mode 100644
index 91d1643..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
-
-public class LuceneXmlConstants {
-  public static final String NAMESPACE= "http://geode.apache.org/schema/lucene";
-  public static final String PREFIX = "lucene";
-  public static final String SERVICE = "service";
-  public static final String NAME = "name";
-  public static final String REGION = "index";
-  public static final String INDEX = "index";
-  public static final String FIELD = "field";
-  public static final String ANALYZER = "analyzer";
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java
deleted file mode 100644
index 5bdbe04..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
-
-import static com.gemstone.gemfire.cache.lucene.internal.xml.LuceneXmlConstants.*;
-
-import com.gemstone.gemfire.cache.CacheXmlException;
-import com.gemstone.gemfire.internal.InternalDataSerializer;
-import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
-import org.apache.lucene.analysis.Analyzer;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-import com.gemstone.gemfire.cache.lucene.internal.LuceneServiceImpl;
-import com.gemstone.gemfire.internal.cache.xmlcache.AbstractXmlParser;
-import com.gemstone.gemfire.internal.cache.xmlcache.RegionAttributesCreation;
-import com.gemstone.gemfire.internal.cache.xmlcache.RegionCreation;
-
-public class LuceneXmlParser extends AbstractXmlParser {
-
-  @Override
-  public String getNamspaceUri() {
-    return NAMESPACE;
-  }
-
-  @Override
-  public void startElement(String uri, String localName, String qName,
-      Attributes atts) throws SAXException {
-    
-    if(!NAMESPACE.equals(uri)) {
-      return;
-    }
-    if(INDEX.equals(localName)) {
-      startIndex(atts);
-    }
-    if(FIELD.equals(localName)) {
-      startField(atts);
-    }
-  }
-
-  private void startField(Attributes atts) {
-    //Ignore any whitespace noise between fields
-    if(stack.peek() instanceof StringBuffer) {
-      stack.pop();
-    }
-    LuceneIndexCreation creation = (LuceneIndexCreation) stack.peek();
-    String name = atts.getValue(NAME);
-    String className = atts.getValue(ANALYZER);
-    if (className == null) {
-      creation.addField(name);
-    } else {
-      Analyzer analyzer = createAnalyzer(className);
-      creation.addFieldAndAnalyzer(name, analyzer);
-    }
-  }
-
-  private void startIndex(Attributes atts) {
-    final RegionCreation region = (RegionCreation) stack.peek();
-    String name = atts.getValue(NAME);
-    LuceneIndexCreation indexCreation = new LuceneIndexCreation();
-    indexCreation.setName(name);
-    indexCreation.setRegion(region);
-    region.getExtensionPoint().addExtension(indexCreation);
-    stack.push(indexCreation);
-  }
-
-  @Override
-  public void endElement(String uri, String localName, String qName)
-      throws SAXException {
-    if(!NAMESPACE.equals(uri)) {
-      return;
-    }
-    if(INDEX.equals(localName)) {
-      endIndex();
-    }
-  }
-
-  private void endIndex() {
-    //Ignore any whitespace noise between fields
-    if(stack.peek() instanceof StringBuffer) {
-      stack.pop();
-    }
-    
-    //Remove the index creation from the stack
-    stack.pop();
-  }
-
-  private Analyzer createAnalyzer(String className) {
-    Object obj;
-    try {
-      Class c = InternalDataSerializer.getCachedClass(className);
-      obj = c.newInstance();
-    }
-    catch (Exception ex) {
-      throw new CacheXmlException(LocalizedStrings.CacheXmlParser_WHILE_INSTANTIATING_A_0.toLocalizedString(className), ex);
-    }
-    if (!(obj instanceof Analyzer)) {
-      throw new CacheXmlException(LocalizedStrings.LuceneXmlParser_CLASS_0_IS_NOT_AN_INSTANCE_OF_ANALYZER.toLocalizedString(className));
-    }
-    return (Analyzer) obj;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java
deleted file mode 100644
index 4eb1ca3..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * Classes for parsing lucene index elements a cache.xml file. See the lucene-1.0.xsd file for
- * the schema.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java
deleted file mode 100644
index 0e0c89b..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * This package provides an integration with Apache Lucene that allows Geode regions to be indexed in a distributed
- * Lucene index and queries using Lucene queries.
- * <p>
- * All indexing and query operations are performed through the {@link com.gemstone.gemfire.cache.lucene.LuceneService} class.
- * See {@link com.gemstone.gemfire.cache.lucene.LuceneService} for an example of how to add a lucene index to a geode region.
- * <p>
- *
- * The Lucene indexes created using this API are stored in geode and colocated with the indexed region, which means they
- * have the same availability guarantees as the underlying region. The indexes are maintained asynchronously, so changes
- * to the region may not be immediately visible in the lucene index.
- */
-
-package com.gemstone.gemfire.cache.lucene;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java
new file mode 100644
index 0000000..6b1a4b4
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.gemstone.gemfire.cache.lucene;
+
+import java.util.Map;
+
+import org.apache.lucene.analysis.Analyzer;
+
+import com.gemstone.gemfire.annotations.Experimental;
+
+
+/**
+ * An lucene index is built over the data stored in a GemFire Region.
+ * <p>
+ * An index is specified using a index name, field names, region name.
+ * <p>
+ * The index name and region name together uniquely identifies the lucene index.
+ * <p>
+ * 
+ */
+@Experimental
+public interface LuceneIndex {
+
+  /**
+   * @return the index name of this index
+   */
+  public String getName();
+
+  /**
+   * @return the region name for this index
+   */
+  public String getRegionPath();
+      
+  /**
+   * @return the indexed field names in a Set
+   */
+  public String[] getFieldNames();
+  
+  /**
+   * @return the field to analyzer map
+   */
+  public Map<String, Analyzer> getFieldAnalyzers();
+  
+  /* 
+   * wait until the current entries in cache are indexed
+   * @param maxWaitInMilliseconds max wait time in millisecond
+   * @return if entries are flushed within maxWait
+   */
+  public boolean waitUntilFlushed(int maxWaitInMillisecond);
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java
new file mode 100644
index 0000000..7cc0977
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.cache.lucene;
+
+import java.util.Collection;
+import java.util.List;
+
+import com.gemstone.gemfire.annotations.Experimental;
+
+/**
+ * Provides wrapper object of Lucene's Query object and execute the search. 
+ * <p>Instances of this interface are created using
+ * {@link LuceneQueryFactory#create}.
+ * 
+ */
+@Experimental
+public interface LuceneQuery<K, V> {
+  /**
+   * Execute search and return keys.
+   */
+  public Collection<K> findKeys() throws LuceneQueryException;
+
+  /**
+   * Execute search and return values.
+   */
+  public Collection<V> findValues() throws LuceneQueryException;
+
+  /**
+   * Execute search and return list of LuceneResultStruct.
+   */
+  public List<LuceneResultStruct<K, V>> findResults() throws LuceneQueryException;
+  /**
+   * Execute the search and get results. 
+   */
+  public PageableLuceneQueryResults<K, V> findPages() throws LuceneQueryException;
+  
+  /**
+   * Get page size setting of current query. 
+   */
+  public int getPageSize();
+  
+  /**
+   * Get limit size setting of current query. 
+   */
+  public int getLimit();
+
+  /**
+   * Get projected fields setting of current query. 
+   */
+  public String[] getProjectedFieldNames();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.java
new file mode 100644
index 0000000..fb03b4a
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.gemstone.gemfire.cache.lucene;
+
+import com.gemstone.gemfire.GemFireCheckedException;
+
+/**
+ * Thrown when a lucene query fails.
+ */
+public class LuceneQueryException extends GemFireCheckedException {
+
+  public LuceneQueryException(final String message) {
+    super(message);
+  }
+
+  public LuceneQueryException(final String message, final Throwable cause) {
+    super(message, cause);
+  }
+
+  public LuceneQueryException(final Throwable cause) {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java
new file mode 100644
index 0000000..8e36bbb
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.cache.lucene;
+
+import org.apache.lucene.queryparser.classic.ParseException;
+
+import com.gemstone.gemfire.annotations.Experimental;
+
+/**
+ * Factory for creating instances of {@link LuceneQuery}.
+ * To get an instance of this factory call {@link LuceneService#createLuceneQueryFactory}.
+ * <P>
+ * To use this factory configure it with the <code>set</code> methods and then
+ * call {@link #create} to produce a {@link LuceneQuery} instance.
+ * 
+ */
+@Experimental
+public interface LuceneQueryFactory {
+  
+  /**
+   * Default query result limit is 100
+   */
+  public static final int DEFAULT_LIMIT = 100;
+  
+  /**
+   *  Default page size of result is 0, which means no pagination
+   */
+  public static final int DEFAULT_PAGESIZE = 0;
+  
+  /**
+   * Set page size for a query result. The default page size is 0 which means no pagination.
+   * If specified negative value, throw IllegalArgumentException
+   * @param pageSize
+   * @return itself
+   */
+  LuceneQueryFactory setPageSize(int pageSize);
+  
+  /**
+   * Set max limit of result for a query
+   * If specified limit is less or equal to zero, throw IllegalArgumentException
+   * @param limit
+   * @return itself
+   */
+  LuceneQueryFactory setResultLimit(int limit);
+  
+  /**
+   * Set a list of fields for result projection.
+   * 
+   * @param fieldNames
+   * @return itself
+   * 
+   * @deprecated TODO This feature is not yet implemented
+   */
+  @Deprecated
+  LuceneQueryFactory setProjectionFields(String... fieldNames);
+  
+  /**
+   * Create wrapper object for lucene's QueryParser object using default standard analyzer.
+   * The queryString is using lucene QueryParser's syntax. QueryParser is for easy-to-use 
+   * with human understandable syntax. 
+   *  
+   * @param regionName region name
+   * @param indexName index name
+   * @param queryString query string in lucene QueryParser's syntax
+   * @param defaultField default field used by the Lucene Query Parser
+   * @param <K> the key type in the query results
+   * @param <V> the value type in the query results
+   * @return LuceneQuery object
+   */
+  public <K, V> LuceneQuery<K, V> create(String indexName, String regionName, String queryString, String defaultField);
+
+  /**
+   * Creates a wrapper object for Lucene's Query object. This {@link LuceneQuery} builder method could be used in
+   * advanced cases, such as cases where Lucene's Query object construction needs Lucene's API over query string.
+   * 
+   * @param indexName index name
+   * @param regionName region name
+   * @param provider constructs and provides a Lucene Query object
+   * @param <K> the key type in the query results
+   * @param <V> the value type in the query results
+   * @return LuceneQuery object
+   */
+  public <K, V> LuceneQuery<K, V> create(String indexName, String regionName, LuceneQueryProvider provider);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java
new file mode 100644
index 0000000..7f1c269
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.gemstone.gemfire.cache.lucene;
+
+import java.io.Serializable;
+
+import org.apache.lucene.search.Query;
+
+import com.gemstone.gemfire.annotations.Experimental;
+import com.gemstone.gemfire.cache.query.QueryException;
+
+/**
+ * The instances of this class will be used for distributing Lucene Query objects and re-constructing the Query object.
+ * If necessary the implementation needs to take care of serializing and de-serializing Lucene Query object. Geode
+ * respects the DataSerializable contract to provide optimal object serialization. For instance,
+ * {@link LuceneQueryProvider}'s toData method will be used to serialize it when it is sent to another member of the
+ * distributed system. Implementation of DataSerializable can provide a zero-argument constructor that will be invoked
+ * when they are read with DataSerializer.readObject.
+ */
+@Experimental
+public interface LuceneQueryProvider extends Serializable {
+  /**
+   * @return A Lucene Query object which could be used for executing Lucene Search on indexed data
+   * @param index local lucene index the query is being constructed against.
+   * @throws LuceneQueryException if the provider fails to construct the query object
+   */
+
+  public Query getQuery(LuceneIndex index) throws LuceneQueryException;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java
new file mode 100644
index 0000000..bc587f5
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.cache.lucene;
+
+import com.gemstone.gemfire.annotations.Experimental;
+
+/**
+ * <p>
+ * Abstract data structure for one item in query result.
+ * 
+ */
+@Experimental
+public interface LuceneResultStruct<K, V> {
+  /**
+   * Return the value associated with the given field name
+   *
+   * @param fieldName the String name of the field
+   * @return the value associated with the specified field
+   * @throws IllegalArgumentException If this struct does not have a field named fieldName
+   */
+  public Object getProjectedField(String fieldName);
+  
+  /**
+   * Return key of the entry
+   *
+   * @return key
+   * @throws IllegalArgumentException If this struct does not contain key
+   */
+  public K getKey();
+  
+  /**
+   * Return value of the entry
+   *
+   * @return value the whole domain object
+   * @throws IllegalArgumentException If this struct does not contain value
+   */
+  public V getValue();
+  
+  /**
+   * Return score of the query 
+   *
+   * @return score
+   * @throws IllegalArgumentException If this struct does not contain score
+   */
+  public float getScore();
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java
new file mode 100644
index 0000000..cf1f735
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.cache.lucene;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.lucene.analysis.Analyzer;
+
+import com.gemstone.gemfire.annotations.Experimental;
+import com.gemstone.gemfire.cache.GemFireCache;
+import com.gemstone.gemfire.cache.lucene.internal.LuceneIndexCreationProfile;
+
+/**
+ * LuceneService instance is a singleton for each cache.
+ * 
+ * It provides handle for managing the {@link LuceneIndex} and create the {@link LuceneQuery}
+ * via {@link LuceneQueryFactory}
+ * 
+ * </p>
+ * Example: <br>
+ * 
+ * <pre>
+ * At client and server JVM, initializing cache will create the LuceneServiceImpl object, 
+ * which is a singleton at each JVM. 
+ * 
+ * At each server JVM, for data region to create index, create the index on fields with default analyzer:
+ * LuceneIndex index = luceneService.createIndex(indexName, regionName, "field1", "field2", "field3"); 
+ * or create index on fields with specified analyzer:
+ * LuceneIndex index = luceneService.createIndex(indexName, regionName, analyzerPerField);
+ * 
+ * We can also create index via cache.xml or gfsh.
+ * 
+ * At client side, create query and run the search:
+ * 
+ * LuceneQuery query = luceneService.createLuceneQueryFactory().setLimit(200).setPageSize(20)
+ * .setResultTypes(SCORE, VALUE, KEY).setFieldProjection("field1", "field2")
+ * .create(indexName, regionName, querystring, analyzer);
+ * 
+ * The querystring is using lucene's queryparser syntax, such as "field1:zhou* AND field2:gzhou@pivotal.io"
+ *  
+ * PageableLuceneQueryResults results = query.search();
+ * 
+ * If pagination is not specified:
+ * List list = results.getNextPage(); // return all results in one getNextPage() call
+ * or if paging is specified:
+ * if (results.hasNextPage()) {
+ *   List page = results.nextPage(); // return resules page by page
+ * }
+ * 
+ * The item of the list is either the domain object or instance of {@link LuceneResultStruct}
+ * </pre>
+ * 
+ *
+ */
+@Experimental
+public interface LuceneService {
+
+  /**
+   * A special field name that indicates that the entire region value should
+   * be indexed. This will only work if the region value is a String or Number, in
+   * which case a lucene document will be created with a single field with this name.
+   */
+  String REGION_VALUE_FIELD = "__REGION_VALUE_FIELD";
+
+  /**
+   * Create a lucene index using default analyzer.
+   * @param fields The fields of the object to index. Only fields listed here will be stored
+   * in the index. Fields should map to PDX fieldNames if the object is serialized with PDX, or
+   * to java fields on the object otherwise. The special field name {{@link #REGION_VALUE_FIELD}}
+   * indicates that the entire value should be stored as a single field in the index.
+   */
+  public void createIndex(String indexName, String regionPath, String... fields);
+  
+  /**
+   * Create a lucene index using specified analyzer per field
+   * 
+   * @param indexName index name
+   * @param regionPath region name
+   * @param analyzerPerField A map of fields to analyzers. See {{@link #createIndex(String, String, String...)}}
+   * for details on valid values for fields. Each field will be tokenized using the provided Analyzer.
+   */
+  public void createIndex(String indexName, String regionPath,
+      Map<String, Analyzer> analyzerPerField);
+
+  /**
+   * Destroy the lucene index
+   * 
+   * @param index index object
+   * @deprecated TODO This feature is not yet implemented
+   */
+  @Deprecated
+  public void destroyIndex(LuceneIndex index);
+  
+  /**
+   * Get the lucene index object specified by region name and index name
+   * @param indexName index name
+   * @param regionPath region name
+   * @return LuceneIndex object
+   */
+  public LuceneIndex getIndex(String indexName, String regionPath);
+  
+  /**
+   * get all the lucene indexes.
+   * @return all index objects in a Collection
+   */
+  public Collection<LuceneIndex> getAllIndexes();
+
+  /**
+   * create LuceneQueryFactory
+   * @return LuceneQueryFactory object
+   */
+  public LuceneQueryFactory createLuceneQueryFactory();
+
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java
new file mode 100644
index 0000000..f83dffa
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.gemstone.gemfire.cache.lucene;
+
+import com.gemstone.gemfire.annotations.Experimental;
+import com.gemstone.gemfire.cache.GemFireCache;
+import com.gemstone.gemfire.cache.lucene.internal.InternalLuceneService;
+import com.gemstone.gemfire.internal.cache.InternalCache;
+
+/**
+ * Class for retrieving or creating the currently running
+ * instance of the LuceneService.
+ *
+ */
+@Experimental
+public class LuceneServiceProvider {
+  /**
+   * Retrieve or create the lucene service for this cache
+   */
+  public static LuceneService get(GemFireCache cache) {
+    InternalCache internalCache = (InternalCache) cache;
+    return internalCache.getService(InternalLuceneService.class);
+  }
+
+  private LuceneServiceProvider() {
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java
new file mode 100644
index 0000000..c2def44
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.gemstone.gemfire.cache.lucene;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.gemstone.gemfire.annotations.Experimental;
+
+/**
+ * <p>
+ * Defines the interface for a container of lucene query result collected from function execution.<br>
+ * 
+ * 
+ * @param <K> The type of the key
+ * @param <V> The type of the value
+ */
+@Experimental
+public interface PageableLuceneQueryResults<K, V> extends Iterator<List<LuceneResultStruct<K,V>>> {
+  /**
+   * @return total number of hits for this query
+   */
+  public int size();
+
+  /**
+   * Returns the maximum score value encountered. Note that in case scores are not tracked, this returns {@link Float#NaN}.
+   */
+  public float getMaxScore();
+
+  /**
+   * Get the next page of results.
+   * 
+   * @return a page of results, or null if there are no more pages
+   */
+  public List<LuceneResultStruct<K, V>> next();
+
+  /**
+   *  True if there another page of results. 
+   */
+  public boolean hasNext();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java
new file mode 100755
index 0000000..1dc716c
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.cache.lucene.internal;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.gemstone.gemfire.InternalGemFireError;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.execute.RegionFunctionContext;
+import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository;
+import com.gemstone.gemfire.cache.lucene.internal.repository.RepositoryManager;
+import com.gemstone.gemfire.cache.lucene.internal.repository.serializer.LuceneSerializer;
+import com.gemstone.gemfire.internal.cache.BucketNotFoundException;
+import com.gemstone.gemfire.internal.cache.BucketRegion;
+import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+import com.gemstone.gemfire.internal.cache.execute.InternalRegionFunctionContext;
+
+public abstract class AbstractPartitionedRepositoryManager implements RepositoryManager {
+
+  /** map of the parent bucket region to the index repository
+   * 
+   * This is based on the BucketRegion in case a bucket is rebalanced, we don't want to 
+   * return a stale index repository. If a bucket moves off of this node and
+   * comes back, it will have a new BucketRegion object.
+   * 
+   * It is weak so that the old BucketRegion will be garbage collected. 
+   */
+  protected final ConcurrentHashMap<Integer, IndexRepository> indexRepositories = new ConcurrentHashMap<Integer, IndexRepository>();
+  
+  /** The user region for this index */
+  protected final PartitionedRegion userRegion;
+  protected final LuceneSerializer serializer;
+  protected final LuceneIndexImpl index; 
+
+  public AbstractPartitionedRepositoryManager(
+      LuceneIndexImpl index,
+      LuceneSerializer serializer) {
+    this.index = index;
+    this.userRegion = (PartitionedRegion)index.getCache().getRegion(index.getRegionPath());
+    this.serializer = serializer;
+  }
+
+  @Override
+  public IndexRepository getRepository(Region region, Object key,
+      Object callbackArg) throws BucketNotFoundException {
+    BucketRegion userBucket = userRegion.getBucketRegion(key, callbackArg);
+    if(userBucket == null) {
+      throw new BucketNotFoundException("User bucket was not found for region " + region + "key " +  key + " callbackarg " + callbackArg);
+    }
+    
+    return getRepository(userBucket.getId());
+  }
+
+  @Override
+  public Collection<IndexRepository> getRepositories(RegionFunctionContext ctx) throws BucketNotFoundException {
+    Region<Object, Object> region = ctx.getDataSet();
+    Set<Integer> buckets = ((InternalRegionFunctionContext) ctx).getLocalBucketSet(region);
+    ArrayList<IndexRepository> repos = new ArrayList<IndexRepository>(buckets.size());
+    for(Integer bucketId : buckets) {
+      BucketRegion userBucket = userRegion.getDataStore().getLocalBucketById(bucketId);
+      if(userBucket == null) {
+        throw new BucketNotFoundException("User bucket was not found for region " + region + "bucket id " + bucketId);
+      } else {
+        repos.add(getRepository(userBucket.getId()));
+      }
+    }
+
+    return repos;
+  }
+
+  public abstract IndexRepository createOneIndexRepository(final Integer bucketId,
+      LuceneSerializer serializer,
+      LuceneIndexImpl index, PartitionedRegion userRegion) throws IOException;
+  
+  /**
+   * Return the repository for a given user bucket
+   */
+  protected IndexRepository getRepository(Integer bucketId) throws BucketNotFoundException {
+    IndexRepository repo = indexRepositories.get(bucketId);
+    if(repo != null && !repo.isClosed()) {
+      return repo;
+    }
+
+    repo = indexRepositories.compute(bucketId, (key, oldRepository) -> {
+      if(oldRepository != null && !oldRepository.isClosed()) {
+        return oldRepository;
+      }
+      if(oldRepository != null) {
+        oldRepository.cleanup();
+      }
+
+      try {
+        return createOneIndexRepository(bucketId, serializer, index, userRegion);
+      } catch(IOException e) {
+        throw new InternalGemFireError("Unable to create index repository", e);
+      }
+
+    });
+
+    if(repo == null) {
+      throw new BucketNotFoundException("Colocated index buckets not found for bucket id " + bucketId);
+    }
+
+    return repo;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java
new file mode 100644
index 0000000..c9c03a5
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.cache.lucene.internal;
+
+import com.gemstone.gemfire.cache.lucene.LuceneIndex;
+import org.apache.lucene.analysis.Analyzer;
+
+import java.util.Map;
+
+public interface IndexListener {
+
+  public void beforeIndexCreated(final String indexName, String regionPath,
+      final Analyzer analyzer, final Map<String, Analyzer> fieldAnalyzers,
+      final String... fields);
+
+  public void afterIndexCreated(LuceneIndex index);
+
+  public void beforeIndexDestroyed(LuceneIndex index);
+
+  public void afterIndexDestroyed(LuceneIndex index);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.java
new file mode 100644
index 0000000..dd916ac
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.cache.lucene.internal;
+
+import com.gemstone.gemfire.cache.lucene.LuceneIndex;
+import org.apache.lucene.analysis.Analyzer;
+
+import java.util.Map;
+
+public class IndexListenerAdapter implements IndexListener {
+  @Override
+  public void beforeIndexCreated(String indexName, String regionPath, Analyzer analyzer,
+      Map<String, Analyzer> fieldAnalyzers, String... fields) {
+  }
+
+  @Override
+  public void afterIndexCreated(LuceneIndex index) {
+  }
+
+  @Override
+  public void beforeIndexDestroyed(LuceneIndex index) {
+  }
+
+  @Override
+  public void afterIndexDestroyed(LuceneIndex index) {
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java
new file mode 100644
index 0000000..e6f01b0
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.cache.lucene.internal;
+
+import java.io.IOException;
+
+import com.gemstone.gemfire.cache.lucene.internal.directory.RegionDirectory;
+import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository;
+import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepositoryImpl;
+import com.gemstone.gemfire.cache.lucene.internal.repository.serializer.LuceneSerializer;
+import com.gemstone.gemfire.internal.cache.BucketNotFoundException;
+import com.gemstone.gemfire.internal.cache.BucketRegion;
+import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+
+public class IndexRepositoryFactory {
+
+  public IndexRepositoryFactory() {
+  }
+
+  public IndexRepository createIndexRepository(final Integer bucketId,
+                                        LuceneSerializer serializer,
+                                        LuceneIndexImpl index, PartitionedRegion userRegion)
+    throws IOException
+  {
+    final IndexRepository repo;
+    LuceneIndexForPartitionedRegion indexForPR = (LuceneIndexForPartitionedRegion)index; 
+    BucketRegion fileBucket = getMatchingBucket(indexForPR.getFileRegion(), bucketId);
+    BucketRegion chunkBucket = getMatchingBucket(indexForPR.getChunkRegion(), bucketId);
+    BucketRegion dataBucket = getMatchingBucket(userRegion, bucketId);
+    if(fileBucket == null || chunkBucket == null) {
+      return null;
+    }
+    RegionDirectory dir = new RegionDirectory(fileBucket, chunkBucket, indexForPR.getFileSystemStats());
+    IndexWriterConfig config = new IndexWriterConfig(indexForPR.getAnalyzer());
+    IndexWriter writer = new IndexWriter(dir, config);
+    repo = new IndexRepositoryImpl(fileBucket, writer, serializer, indexForPR.getIndexStats(), dataBucket);
+    return repo;
+  }
+
+  /**
+   * Find the bucket in region2 that matches the bucket id from region1.
+   */
+  protected BucketRegion getMatchingBucket(PartitionedRegion region, Integer bucketId) {
+    //Force the bucket to be created if it is not already
+    region.getOrCreateNodeForBucketWrite(bucketId, null);
+
+    return region.getDataStore().getLocalBucketById(bucketId);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java
new file mode 100644
index 0000000..27b4820
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.gemstone.gemfire.cache.lucene.internal;
+
+import com.gemstone.gemfire.cache.lucene.LuceneIndex;
+import com.gemstone.gemfire.cache.lucene.internal.repository.RepositoryManager;
+
+public interface InternalLuceneIndex extends LuceneIndex {
+  
+  public RepositoryManager getRepositoryManager();
+
+  /**
+   * Dump the files for this index to the given directory.
+   */
+  public void dumpFiles(String directory);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java
new file mode 100644
index 0000000..403853e
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.gemstone.gemfire.cache.lucene.internal;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.lucene.LuceneService;
+import com.gemstone.gemfire.internal.cache.CacheService;
+import com.gemstone.gemfire.internal.cache.extension.Extension;
+
+public interface InternalLuceneService extends LuceneService, Extension<Cache>, CacheService {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java
new file mode 100644
index 0000000..29fb159
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.gemstone.gemfire.cache.lucene.internal;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.InternalGemFireError;
+import com.gemstone.gemfire.cache.Operation;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionDestroyedException;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEvent;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
+import com.gemstone.gemfire.cache.lucene.internal.repository.RepositoryManager;
+import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository;
+import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
+import com.gemstone.gemfire.internal.cache.BucketNotFoundException;
+import com.gemstone.gemfire.internal.cache.CacheObserverHolder;
+import com.gemstone.gemfire.internal.cache.PrimaryBucketException;
+import com.gemstone.gemfire.internal.cache.partitioned.Bucket;
+import com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientProxy.TestHook;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * An Async event queue listener that writes all of the
+ * events in batches to Lucene
+ */
+public class LuceneEventListener implements AsyncEventListener {
+  Logger logger = LogService.getLogger();
+
+  private final RepositoryManager repositoryManager;
+  
+  public LuceneEventListener(RepositoryManager repositoryManager) {
+    this.repositoryManager = repositoryManager;
+  }
+
+  @Override
+  public void close() {
+  }
+
+  @Override
+  public boolean processEvents(List<AsyncEvent> events) {
+    // Try to get a PDX instance if possible, rather than a deserialized object
+    DefaultQuery.setPdxReadSerialized(true);
+
+    Set<IndexRepository> affectedRepos = new HashSet<IndexRepository>();
+
+    try {
+      for (AsyncEvent event : events) {
+        Region region = event.getRegion();
+        Object key = event.getKey();
+        Object callbackArgument = event.getCallbackArgument();
+
+        IndexRepository repository = repositoryManager.getRepository(region, key, callbackArgument);
+
+        Operation op = event.getOperation();
+
+        if (op.isCreate()) {
+          repository.update(key, event.getDeserializedValue());
+        } else if (op.isUpdate()) {
+          repository.update(key, event.getDeserializedValue());
+        } else if (op.isDestroy()) {
+          repository.delete(key);
+        } else if (op.isInvalidate()) {
+          repository.delete(key);
+        } else {
+          throw new InternalGemFireError("Unhandled operation " + op + " on " + event.getRegion());
+        }
+        affectedRepos.add(repository);
+      }
+
+      for(IndexRepository repo : affectedRepos) {
+        repo.commit();
+      }
+      return true;
+    } catch(BucketNotFoundException | RegionDestroyedException | PrimaryBucketException e) {
+      logger.debug("Bucket not found while saving to lucene index: " + e.getMessage());
+      return false;
+    } catch(IOException e) {
+      logger.error("Unable to save to lucene index", e);
+      return false;
+    } finally {
+      DefaultQuery.setPdxReadSerialized(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java
new file mode 100644
index 0000000..de331ea
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.cache.lucene.internal;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.CacheServiceProfile;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.*;
+
+public class LuceneIndexCreationProfile implements CacheServiceProfile, DataSerializable {
+
+  private String indexName;
+
+  private String[] fieldNames;
+
+  private String analyzerClass;
+
+  private Map<String, String> fieldAnalyzers;
+
+  private String regionPath;
+
+  /* Used by DataSerializer */
+  public LuceneIndexCreationProfile() {}
+
+  public LuceneIndexCreationProfile(String indexName, String regionPath, String[] fieldNames, Analyzer analyzer,
+                                    Map<String, Analyzer> fieldAnalyzers) {
+    this.indexName = indexName;
+    this.regionPath = regionPath;
+    this.fieldNames = fieldNames;
+    this.analyzerClass = analyzer.getClass().getSimpleName();
+    initializeFieldAnalyzers(fieldAnalyzers);
+  }
+
+  public String getIndexName() {
+    return this.indexName;
+  }
+
+  public String[] getFieldNames() {
+    return this.fieldNames;
+  }
+
+  public String getAnalyzerClass() {
+    return this.analyzerClass;
+  }
+
+  public Map<String, String> getFieldAnalyzers() {
+    return this.fieldAnalyzers;
+  }
+
+  protected void initializeFieldAnalyzers(Map<String, Analyzer> fieldAnalyzers) {
+    this.fieldAnalyzers = new HashMap<>();
+    for (String field : fieldNames) {
+     if(fieldAnalyzers != null && !fieldAnalyzers.isEmpty())  {
+        this.fieldAnalyzers.put(field, fieldAnalyzers.get(field) == null ? StandardAnalyzer.class.getSimpleName() : fieldAnalyzers.get(field).getClass().getSimpleName());
+      } else {
+        this.fieldAnalyzers.put(field, StandardAnalyzer.class.getSimpleName());
+      }
+    }
+  }
+
+  @Override
+  public String getId() {
+    return "lucene_"+LuceneServiceImpl.getUniqueIndexName(indexName, regionPath);
+  }
+
+  @Override
+  public String checkCompatibility(String regionPath, CacheServiceProfile profile) {
+    String result = null;
+    LuceneIndexCreationProfile remoteProfile = (LuceneIndexCreationProfile) profile;
+    if (remoteProfile == null) {
+      // TODO This can occur if one member defines no indexes but another one does. Currently this is caught by the async event id checks.
+    } else {
+      // Verify fields are the same
+      if (!Arrays.equals(remoteProfile.getFieldNames(), getFieldNames())) {
+        return LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_FIELDS_2_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_FIELDS_3
+            .toString(getIndexName(), regionPath, Arrays.toString(getFieldNames()), Arrays.toString(remoteProfile.getFieldNames()));
+      }
+
+      // Verify the analyzer class is the same
+      // Note: This test will currently only fail if per-field analyzers are used in one member but not another,
+      // This condition will be caught in the tests below so this test is commented out. If we ever allow the user
+      // to configure a single analyzer for all fields, then this test will be useful again.
+      /*
+      if (!remoteLuceneIndexProfile.getAnalyzerClass().isInstance(getAnalyzer())) {
+        result = LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_ANALYZER_2_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_ANALYZER_3
+            .toString(indexName, regionPath, remoteLuceneIndexProfile.getAnalyzerClass().getName(), analyzer.getClass().getName());
+      }
+      */
+
+      // Iterate the existing analyzers and compare them to the input analyzers
+      // Note: This is currently destructive to the input field analyzers map which should be ok since its a transient object.
+      if (!getFieldAnalyzers().equals(remoteProfile.getFieldAnalyzers())) {
+        if (getFieldAnalyzers().size() != remoteProfile.getFieldAnalyzers().size()) {
+          return LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_FIELDS_2_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_FIELDS_3
+              .toString(getIndexName(), regionPath, 
+                  Arrays.toString(getFieldAnalyzers().keySet().toArray()),
+                  Arrays.toString(remoteProfile.getFieldAnalyzers().keySet().toArray()));
+        }
+        // now the 2 maps should have the same size
+        for (String field:getFieldAnalyzers().keySet()) {
+          if (!remoteProfile.getFieldAnalyzers().get(field).equals(getFieldAnalyzers().get(field))) {
+            return LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_ANALYZER_2_ON_FIELD_3_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_ANALYZER_4_ON_THAT_FIELD
+              .toString(getIndexName(), regionPath,
+                    getFieldAnalyzers().get(field), field,
+                    remoteProfile.getFieldAnalyzers().get(field)); 
+          }
+        }
+      }
+    }
+    return result;
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writeString(this.indexName, out);
+    DataSerializer.writeString(this.regionPath, out);
+    DataSerializer.writeStringArray(this.fieldNames, out);
+    DataSerializer.writeString(this.analyzerClass, out);
+    DataSerializer.writeHashMap(this.fieldAnalyzers, out);
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.indexName = DataSerializer.readString(in);
+    this.regionPath = DataSerializer.readString(in);
+    this.fieldNames = DataSerializer.readStringArray(in);
+    this.analyzerClass = DataSerializer.readString(in);
+    this.fieldAnalyzers = DataSerializer.readHashMap(in);
+  }
+
+  public String toString() {
+    return new StringBuilder()
+        .append(getClass().getSimpleName())
+        .append("[")
+        .append("indexName=")
+        .append(this.indexName)
+        .append("; fieldNames=")
+        .append(Arrays.toString(this.fieldNames))
+        .append("; analyzerClass=")
+        .append(this.analyzerClass)
+        .append("; fieldAnalyzers=")
+        .append(this.fieldAnalyzers)
+        .append("]")
+        .toString();
+  }
+
+  public String getRegionPath() {
+    return this.regionPath;
+  }
+}