// Path: src/main/java/org/neo4j/index/lucene/ValueContext.java
// public class ValueContext
// {
//     private final Object value;
//     private boolean indexNumeric;
// 
//     public ValueContext( Object value )
//     {
//         this.value = value;
//     }
//     
//     /**
//      * @return the value object specified in the constructor.
//      */
//     public Object getValue()
//     {
//         return value;
//     }
// 
//     /**
//      * Returns a ValueContext to be used with {@link Index#add(PropertyContainer, String, Object)}
//      *
//      * @return a numeric ValueContext
//      */
//     public ValueContext indexNumeric()
//     {
//         if ( !( this.value instanceof Number ) )
//         {
//             throw new IllegalStateException( "Value should be a Number, is " + value +
//                     " (" + value.getClass() + ")" );
//         }
//         this.indexNumeric = true;
//         return this;
//     }
//     
//     /**
//      * Returns the string representation of the value given in the constructor,
//      * or the unmodified value if {@link #indexNumeric()} has been called.
//      * 
//      * @return the, by the user, intended value to index.
//      */
//     public Object getCorrectValue()
//     {
//         return this.indexNumeric ? this.value : this.value.toString();
//     }
//     
//     @Override
//     public String toString()
//     {
//         return value.toString();
//     }
// 
//     /**
//      * Convience method to add a numeric value to an index.
//      * @param value The value to add
//      * @return A ValueContext that can be used with {@link Index#add(PropertyContainer, String, Object)}
//      */
//     public static ValueContext numeric(Number value)
//     {
//         return new ValueContext(value).indexNumeric();
//     }
// }
// 
// Path: src/main/java/org/neo4j/index/impl/lucene/LuceneDataSource.java
// public static final Version LUCENE_VERSION = Version.LUCENE_40;
// 
// Path: src/main/java/org/neo4j/index/impl/lucene/LuceneDataSource.java
// static Directory getDirectory( String storeDir,
//         IndexIdentifier identifier ) throws IOException
// {
//     return FSDirectory.open( getFileDirectory( storeDir, identifier) );
// }


import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.neo4j.graphdb.index.BatchInserterIndex;
import org.neo4j.graphdb.index.IndexHits;
import org.neo4j.helpers.Pair;
import org.neo4j.index.lucene.ValueContext;
import org.neo4j.kernel.impl.cache.LruCache;
import org.neo4j.kernel.impl.util.IoPrimitiveUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import static org.neo4j.index.impl.lucene.LuceneDataSource.LUCENE_VERSION;
import static org.neo4j.index.impl.lucene.LuceneDataSource.getDirectory;
    }

    @Override
    public void add( long entityId, Map<String, Object> properties )
    {
        try
        {
            Document document = identifier.entityType.newDocument( entityId );
            for ( Map.Entry<String, Object> entry : properties.entrySet() )
            {
                String key = entry.getKey();
                Object value = entry.getValue();
                addSingleProperty(entityId, document, key, value);
            }
            writer.addDocument( document );
            if ( ++updateCount == commitBatchSize )
            {
                writer.commit();
                updateCount = 0;
            }
        }
        catch ( IOException e )
        {
            throw new RuntimeException( e );
        }
    }

    private void addSingleProperty( long entityId, Document document, String key, Object value ) {
        for ( Object oneValue : IoPrimitiveUtils.asArray(value) )
        {
// Path: src/main/java/org/neo4j/index/lucene/ValueContext.java
// public class ValueContext
// {
//     private final Object value;
//     private boolean indexNumeric;
// 
//     public ValueContext( Object value )
//     {
//         this.value = value;
//     }
//     
//     /**
//      * @return the value object specified in the constructor.
//      */
//     public Object getValue()
//     {
//         return value;
//     }
// 
//     /**
//      * Returns a ValueContext to be used with {@link Index#add(PropertyContainer, String, Object)}
//      *
//      * @return a numeric ValueContext
//      */
//     public ValueContext indexNumeric()
//     {
//         if ( !( this.value instanceof Number ) )
//         {
//             throw new IllegalStateException( "Value should be a Number, is " + value +
//                     " (" + value.getClass() + ")" );
//         }
//         this.indexNumeric = true;
//         return this;
//     }
//     
//     /**
//      * Returns the string representation of the value given in the constructor,
//      * or the unmodified value if {@link #indexNumeric()} has been called.
//      * 
//      * @return the, by the user, intended value to index.
//      */
//     public Object getCorrectValue()
//     {
//         return this.indexNumeric ? this.value : this.value.toString();
//     }
//     
//     @Override
//     public String toString()
//     {
//         return value.toString();
//     }
// 
//     /**
//      * Convience method to add a numeric value to an index.
//      * @param value The value to add
//      * @return A ValueContext that can be used with {@link Index#add(PropertyContainer, String, Object)}
//      */
//     public static ValueContext numeric(Number value)
//     {
//         return new ValueContext(value).indexNumeric();
//     }
// }
// 
// Path: src/main/java/org/neo4j/index/impl/lucene/LuceneDataSource.java
// public static final Version LUCENE_VERSION = Version.LUCENE_40;
// 
// Path: src/main/java/org/neo4j/index/impl/lucene/LuceneDataSource.java
// static Directory getDirectory( String storeDir,
//         IndexIdentifier identifier ) throws IOException
// {
//     return FSDirectory.open( getFileDirectory( storeDir, identifier) );
// }


// Path: src/main/java/org/neo4j/index/impl/lucene/LuceneBatchInserterIndex.java
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.neo4j.graphdb.index.BatchInserterIndex;
import org.neo4j.graphdb.index.IndexHits;
import org.neo4j.helpers.Pair;
import org.neo4j.index.lucene.ValueContext;
import org.neo4j.kernel.impl.cache.LruCache;
import org.neo4j.kernel.impl.util.IoPrimitiveUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import static org.neo4j.index.impl.lucene.LuceneDataSource.LUCENE_VERSION;
import static org.neo4j.index.impl.lucene.LuceneDataSource.getDirectory;

    }

    @Override
    public void add( long entityId, Map<String, Object> properties )
    {
        try
        {
            Document document = identifier.entityType.newDocument( entityId );
            for ( Map.Entry<String, Object> entry : properties.entrySet() )
            {
                String key = entry.getKey();
                Object value = entry.getValue();
                addSingleProperty(entityId, document, key, value);
            }
            writer.addDocument( document );
            if ( ++updateCount == commitBatchSize )
            {
                writer.commit();
                updateCount = 0;
            }
        }
        catch ( IOException e )
        {
            throw new RuntimeException( e );
        }
    }

    private void addSingleProperty( long entityId, Document document, String key, Object value ) {
        for ( Object oneValue : IoPrimitiveUtils.asArray(value) )
        {
            boolean isValueContext = oneValue instanceof ValueContext;