Index: content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstBeanIteratorImpl.java
===================================================================
--- content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstBeanIteratorImpl.java	(revision 0)
+++ content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstBeanIteratorImpl.java	(revision 0)
@@ -0,0 +1,75 @@
+package org.hippoecm.hst.content.beans.solr;
+
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.hippoecm.hst.content.beans.HstBean;
+import org.hippoecm.hst.content.beans.standard.HippoBean;
+
+public class HstBeanIteratorImpl implements HstBeanIterator<HstBean> {
+
+    private List<HstBean> beans;
+    private  Session session;
+    private int position = 0;
+    
+    public HstBeanIteratorImpl(List<HstBean> beans, Session session) {
+       this.beans = beans;
+       this.session = session;
+    }
+    
+    @Override
+    public int getPosition() {
+        return position;
+    }
+
+    @Override
+    public int getSize() {
+        return beans.size();
+    }
+
+    @Override
+    public void skip(int skipNum) {
+        position+=skipNum;
+        if(position >= getSize()) {
+            position = getSize() - 1;
+        }
+    }
+
+    @Override
+    public boolean hasNext() {
+        return position < getSize();
+    }
+ 
+    @Override
+    public HstBean next() {
+        if(position >= getSize()) {
+            throw new NoSuchElementException("No next bean");
+        }
+        HstBean next = beans.get(position);
+        position++;
+        if(next instanceof HippoBean) {
+            // attach jcr node again
+            try {
+                HippoBean bean = (HippoBean)next;
+                Node jcrNode = session.getNodeByIdentifier(bean.getCanonicalUUID());
+                bean.setNode(jcrNode);
+            } catch (ItemNotFoundException e) {
+                // log warning : cannot attach jcr node 
+            } catch (RepositoryException e) {
+                // log warning : cannot attach jcr node  
+            }
+        }
+        return next;
+    }
+
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException("Remove is not supported");
+    }
+
+}
Index: content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstDocumentObjectBinder.java
===================================================================
--- content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstDocumentObjectBinder.java	(revision 0)
+++ content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstDocumentObjectBinder.java	(revision 0)
@@ -0,0 +1,419 @@
+package org.hippoecm.hst.content.beans.solr;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Array;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+
+import org.apache.solr.client.solrj.beans.DocumentObjectBinder;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.SolrInputDocument;
+import org.hippoecm.hst.content.beans.index.IndexField;
+import org.hippoecm.hst.util.ForkedISO8601;
+
+/**
+ * A class to map objects to and from solr documents.
+ * 
+ * @version $Id: DocumentObjectBinder.java 812759 2009-09-09 03:49:18Z noble $
+ * @since solr 1.3
+ */
+public class HstDocumentObjectBinder extends DocumentObjectBinder {
+  private final Map<Class, List<DocField>> infocache = new ConcurrentHashMap<Class, List<DocField>>();
+
+  private final static String HST_BEAN_FQN_CLAZZ_NAME = "hst_bean_fqn_clazz_name";
+  public HstDocumentObjectBinder() {
+  }
+
+  @Override
+  public <T> List<T> getBeans(Class<T> clazz, SolrDocumentList solrDocList) {
+       
+    List<T> result = new ArrayList<T>();
+    for (int j = 0; j < solrDocList.size(); j++) {
+        SolrDocument sdoc = solrDocList.get(j);
+
+        String beanClazz = (String) sdoc.get(HST_BEAN_FQN_CLAZZ_NAME);
+        if (beanClazz == null) {
+            // we cannot return beans that do not have a 'clazz'
+            continue;
+        }
+
+        Object obj = null;
+        try {
+            Class c = Thread.currentThread().getContextClassLoader().loadClass(beanClazz);
+            if (!clazz.isAssignableFrom(c)) {
+                continue;
+            }
+            obj = c.newInstance();
+            List<DocField> fields = getDocFields(c);
+            for (int i = 0; i < fields.size(); i++) {
+                DocField docField = fields.get(i);
+                docField.inject(obj, sdoc);
+            }
+            result.add((T) obj);
+        } catch (Exception e) {
+            throw new RuntimeException("Could not instantiate object of " + clazz, e);
+        }
+
+    }
+    return result;
+  }
+  
+
+  @Override
+  public SolrInputDocument toSolrInputDocument( Object obj )
+  {
+    List<DocField> fields = getDocFields( obj.getClass() );
+    if( fields.isEmpty() ) {
+      throw new RuntimeException( "class: "+obj.getClass()+" does not define any fields." );
+    }
+    
+    SolrInputDocument doc = new SolrInputDocument();
+    for( DocField field : fields ) {
+      doc.setField( field.name, field.get( obj ), 1.0f );
+    }
+    // default field name we always add:
+    doc.setField( HST_BEAN_FQN_CLAZZ_NAME, obj.getClass().getName(), 1.0f );
+    return doc;
+  }
+  
+
+  private List<DocField> getDocFields( Class clazz )
+  {
+        boolean caching = false;
+        if (caching) {
+            List<DocField> fields = infocache.get(clazz);
+            if (fields == null) {
+                synchronized (infocache) {
+                    infocache.put(clazz, fields = collectInfo(clazz));
+                }
+            }
+            return fields;
+        } else {
+            return collectInfo(clazz);
+        }
+
+  }
+
+
+  private List<DocField> collectInfo(Class clazz) {
+    List<DocField> fields = new ArrayList<DocField>();
+    Class superClazz = clazz;
+    ArrayList<AccessibleObject> members = new ArrayList<AccessibleObject>();
+    while (superClazz != null && superClazz != Object.class) {
+         
+      members.addAll(Arrays.asList(superClazz.getDeclaredFields()));
+      members.addAll(Arrays.asList(superClazz.getDeclaredMethods()));
+      superClazz = superClazz.getSuperclass();
+    }
+    for (AccessibleObject member : members) {
+      if (member.isAnnotationPresent(IndexField.class)) {
+        member.setAccessible(true);
+        fields.add(new DocField(member));
+      }
+    }
+    return fields;
+  }
+
+  private static class DocField {
+    private String name;
+    private java.lang.reflect.Field field;
+    private Method getter;
+    private Class type;
+    private boolean isArray = false, isList=false;
+
+    /*
+     * dynamic fields may use a Map based data structure to bind a given field.
+     * if a mapping is done using, "Map<String, List<String>> foo", <code>isContainedInMap</code>
+     * is set to <code>TRUE</code> as well as <code>isList</code> is set to <code>TRUE</code>
+     */
+    boolean isContainedInMap =false;
+    private Pattern dynamicFieldNamePatternMatcher;
+
+    public DocField(AccessibleObject member) {
+      if (member instanceof java.lang.reflect.Field) {
+        field = (java.lang.reflect.Field) member;
+      } else {
+        getter = (Method) member;
+      }
+      IndexField annotation = member.getAnnotation(IndexField.class);
+      storeName(annotation);
+      storeType();
+      
+      // Look for a matching getter for either field or setter. 
+      
+      String gname = null;
+      Class<?> declaringClass = null;
+      if( getter != null ) {
+       // we already have a getter
+      } else {
+          gname = "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
+          declaringClass = field.getDeclaringClass();
+          if(gname != null && declaringClass != null) {
+          try {
+              getter = declaringClass.getMethod( gname, (Class[])null );
+            }
+            catch( Exception ex ) {
+              // no getter -- don't worry about it...
+              if( type == Boolean.class ) {
+                gname = "is" + gname.substring( 3 );
+                try {
+                  getter = declaringClass.getMethod( gname, (Class[])null );
+                }
+                catch( Exception ex2 ) {
+                  // no getter -- don't worry about it...
+                }
+              }
+            }
+          }
+      }
+      
+      
+      
+    }
+
+    private void storeName(IndexField annotation) {
+      if (annotation.name().equals(IndexField.DEFAULT)) {
+        if (field != null) {
+          name = field.getName();
+        } else {
+          String getterName = getter.getName();
+          if (getterName.startsWith("get") && getterName.length() > 3) {
+            name = getterName.substring(3, 4).toLowerCase() + getterName.substring(4);
+          } else {
+            name = getter.getName();
+          }
+        }
+      }
+      //dynamic fields are annotated as @Field("categories_*")
+      else if(annotation.name().indexOf('*') >= 0){
+        //if the field was annotated as a dynamic field, convert the name into a pattern
+        //the wildcard (*) is supposed to be either a prefix or a suffix, hence the use of replaceFirst
+        name = annotation.name().replaceFirst("\\*", "\\.*");
+        dynamicFieldNamePatternMatcher = Pattern.compile("^"+name+"$");
+      } else {
+        name = annotation.name();
+      }
+    }
+
+    private void storeType() {
+      if (field != null) {
+        type = field.getType();
+      } else { 
+        type = getter.getReturnType();
+      }
+      if(type == Collection.class || type == List.class || type == ArrayList.class) {
+        type = Object.class;
+        isList = true;
+      } else if(type == byte[].class){
+        //no op
+      }else if (type.isArray()) {
+        isArray = true;
+        type = type.getComponentType();
+      }
+      //corresponding to the support for dynamicFields
+      else if (type == Map.class || type == HashMap.class) {
+        isContainedInMap = true;
+        //assigned a default type
+        type = Object.class;
+        if(field != null){
+          if(field.getGenericType() instanceof ParameterizedType){
+            //check what are the generic values
+            ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
+            Type[] types = parameterizedType.getActualTypeArguments();
+            if(types != null && types.length == 2 && types[0] == String.class){
+              //the key should always be String
+              //Raw and primitive types
+              if(types[1] instanceof Class){
+                //the value could be multivalued then it is a List ,Collection,ArrayList
+                if(types[1]== Collection.class || types[1] == List.class || types[1] == ArrayList.class){
+                  type = Object.class;
+                  isList = true;
+                }else{
+                  //else assume it is a primitive and put in the source type itself
+                  type = (Class) types[1];
+                }
+              }
+              //Of all the Parameterized types, only List is supported
+              else if(types[1] instanceof ParameterizedType){
+                Type rawType = ((ParameterizedType)types[1]).getRawType();
+                if(rawType== Collection.class || rawType == List.class || rawType == ArrayList.class){
+                  type = Object.class;
+                  isList = true;
+                }
+              }
+              //Array types
+              else if(types[1] instanceof GenericArrayType){
+                type = (Class) ((GenericArrayType) types[1]).getGenericComponentType();
+                isArray = true;
+              }
+              //Throw an Exception if types are not known
+              else{
+                throw new RuntimeException("Allowed type for values of mapping a dynamicField are : " +
+                    "Object, Object[] and List");
+              }
+            }
+          }
+        }
+      }
+    }
+
+    /**
+     * Called by the {@link #inject} method to read the value(s) for a field
+     * This method supports reading of all "matching" fieldName's in the <code>SolrDocument</code>
+     *
+     * Returns <code>SolrDocument.getFieldValue</code> for regular fields,
+     * and <code>Map<String, List<Object>></code> for a dynamic field. The key is all matching fieldName's.
+     */
+    @SuppressWarnings("unchecked")
+    private Object getFieldValue(SolrDocument sdoc){
+      Object fieldValue = sdoc.getFieldValue(name);
+      if(fieldValue != null) {
+        //this is not a dynamic field. so return te value
+        return fieldValue;
+      }
+      //reading dynamic field values
+      if(dynamicFieldNamePatternMatcher != null){
+        Map<String, Object> allValuesMap = null;
+        ArrayList allValuesList = null;
+        if(isContainedInMap){
+         allValuesMap = new HashMap<String, Object>();
+        } else {
+          allValuesList = new ArrayList();
+        }
+        for(String field : sdoc.getFieldNames()){
+          if(dynamicFieldNamePatternMatcher.matcher(field).find()){
+            Object val = sdoc.getFieldValue(field);
+            if(val == null) continue;
+            if(isContainedInMap){
+              if(isList){
+                if (!(val instanceof List)) {
+                  ArrayList al = new ArrayList();
+                  al.add(val);
+                  val = al;
+                }
+              } else if(isArray){
+                if (!(val instanceof List)) {
+                  Object[] arr= (Object[]) Array.newInstance(type,1);
+                  arr[0] = val;
+                  val= arr;
+                } else {
+                  val = Array.newInstance(type,((List)val).size());
+                }
+              }
+              allValuesMap.put(field, val);
+            }else {
+              if (val instanceof Collection) {
+                allValuesList.addAll((Collection) val);
+              } else {
+                allValuesList.add(val);
+              }
+            }
+          }
+        }
+        if (isContainedInMap) {
+          return allValuesMap.isEmpty() ? null : allValuesMap;
+        } else {
+          return allValuesList.isEmpty() ? null : allValuesList;
+        }
+      }
+      return null;
+    }
+    <T> void inject(T obj, SolrDocument sdoc) {
+      Object val = getFieldValue(sdoc);
+      if(val == null) {
+        return;
+      }
+      if(isArray && !isContainedInMap){
+        List list = null;
+        if(val.getClass().isArray()){
+          set(obj,val);
+          return;
+        } else if (val instanceof List) {
+          list = (List) val;
+        } else{
+          list = new ArrayList();
+          list.add(val);
+        }
+        set(obj, list.toArray((Object[]) Array.newInstance(type,list.size())));        
+      } else if(isList && !isContainedInMap){
+        if (!(val instanceof List)) {
+          ArrayList list = new ArrayList();
+          list.add(val);
+          val =  list;
+        }
+        set(obj, val);
+      } else if(isContainedInMap){
+        if (val instanceof Map) {
+          set(obj,  val);
+        }
+      } else {
+        set(obj, val);
+      }
+
+    }
+
+
+    private void set(Object obj, Object v) {
+      if(v!= null && type == ByteBuffer.class && v.getClass()== byte[].class) {
+        v = ByteBuffer.wrap((byte[])v);
+      }
+      try {
+        if (field != null) { 
+          field.set(obj, v);
+        }
+      } 
+      catch (Exception e) {
+        throw new RuntimeException("Exception while setting value : "+v+" on " +  field , e);
+      }
+    }
+ 
+
+    public Object get( final Object obj )
+    {  
+     
+      Object val;
+      if (field != null) {
+        try { 
+          val = field.get(obj);
+          if(val != null) {
+              return format(val);
+          }
+        } 
+        catch (Exception e) {        
+          throw new RuntimeException("Exception while getting value: " + field, e);
+        }
+      }
+      
+      if (getter != null) {
+            try {
+                return format( getter.invoke(obj, (Object[]) null));
+            } catch (Exception e) {
+                throw new RuntimeException("Exception while getting value: " + getter, e);
+            }
+      } 
+      
+      return null;
+    }
+
+    private Object format(Object val) {
+        if(val instanceof Calendar) {
+            return  ForkedISO8601.format((Calendar)val)+"Z";
+        }
+        return val;
+    }
+  }
+}
+
Index: content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQueryImpl.java
===================================================================
--- content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQueryImpl.java	(revision 0)
+++ content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQueryImpl.java	(revision 0)
@@ -0,0 +1,137 @@
+package org.hippoecm.hst.content.beans.solr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Session;
+
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrDocumentList;
+import org.hippoecm.hst.content.beans.HstBean;
+import org.hippoecm.hst.content.beans.query.exceptions.QueryException;
+import org.hippoecm.hst.content.beans.query.filter.BaseFilter;
+import org.hippoecm.hst.content.beans.query.filter.Filter;
+
+public class HstSolrQueryImpl implements HstSolrQuery {
+
+    private SolrServer server;
+
+    private Session session;
+    
+    private String query;
+    
+    public HstSolrQueryImpl(Session session, SolrServer server) {
+        this.server = server;
+        this.session = session;
+    }
+    
+    
+    public HstSolrQueryImpl(Session session, SolrServer server, String query) {
+        this.server = server;
+        this.session = session;
+        this.query = query;
+    }
+    
+    
+    @Override
+    public void addOrderByAscending(String fieldNameAttribute) {
+       throw new UnsupportedOperationException("not yet implemented");
+    }
+
+
+
+    @Override
+    public void addOrderByDescending(String fieldNameAttribute) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+
+
+    @Override
+    public Filter createFilter() {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+
+
+    @Override
+    public HstSolrQueryResult execute() throws QueryException {
+        SolrQuery solrQuery = new SolrQuery();
+         
+        if(query == null) {
+            solrQuery.setQuery( "*:*" );
+        } else {
+
+            //solrQuery.setQuery("constructionDate:[1976-03-06T23:59:59.999Z TO *]");
+            solrQuery.setQuery(query);
+        }
+        solrQuery.addSortField( "name", SolrQuery.ORDER.asc );
+        
+        solrQuery.set("limit", 50);
+        
+        try {
+            QueryResponse rsp = server.query( solrQuery );
+           
+            SolrDocumentList docs = rsp.getResults();
+            
+            System.out.println(rsp.getSpellCheckResponse());
+            System.out.println(docs.size());
+            
+            
+            List<HstBean> bindedBeans = new HstDocumentObjectBinder().getBeans(HstBean.class, docs);
+            
+            //List<TextItem> beans = rsp.getBeans(TextItem.class);
+            
+            return new HstSolrQueryResultImpl(new ArrayList<HstBean>(bindedBeans), session);
+            
+        } catch (SolrServerException e) {
+           throw new QueryException("Exception during querying Solr server", e);
+        }
+    }
+
+
+
+    @Override
+    public BaseFilter getFilter() {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+    @Override
+    public int getLimit() {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+    @Override
+    public int getOffset() {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+    @Override
+    public String getQueryAsString() throws QueryException {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+    @Override
+    public void setFilter(BaseFilter filter) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+    @Override
+    public void setLimit(int limit) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+
+
+    @Override
+    public void setOffset(int offset) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+    
+    
+    
+
+}
Index: content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQueryResultImpl.java
===================================================================
--- content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQueryResultImpl.java	(revision 0)
+++ content-beans/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQueryResultImpl.java	(revision 0)
@@ -0,0 +1,35 @@
+package org.hippoecm.hst.content.beans.solr;
+
+import java.util.List;
+
+import javax.jcr.Session;
+
+import org.hippoecm.hst.content.beans.HstBean;
+
+public class HstSolrQueryResultImpl implements HstSolrQueryResult {
+
+    private List<HstBean> beans;
+    private  Session session;
+    
+    
+    public HstSolrQueryResultImpl(List<HstBean> beans, Session session) {
+       this.beans = beans;
+       this.session = session;
+    }
+
+    @Override
+    public HstBeanIterator<HstBean> getHstBeans() {
+        return new HstBeanIteratorImpl(beans, session);
+    }
+
+    @Override
+    public int getSize() {
+        return beans.size();
+    }
+
+    @Override
+    public int getTotalSize() {
+        return beans.size();
+    }
+
+}
Index: content-beans/src/main/java/org/hippoecm/hst/content/beans/standard/HippoItem.java
===================================================================
--- content-beans/src/main/java/org/hippoecm/hst/content/beans/standard/HippoItem.java	(revision 29199)
+++ content-beans/src/main/java/org/hippoecm/hst/content/beans/standard/HippoItem.java	(working copy)
@@ -28,6 +28,7 @@
 import javax.jcr.Session;
 
 import org.hippoecm.hst.content.beans.ObjectBeanManagerException;
+import org.hippoecm.hst.content.beans.index.IndexField;
 import org.hippoecm.hst.content.beans.manager.ObjectConverter;
 import org.hippoecm.hst.content.beans.query.HstContextualizeException;
 import org.hippoecm.hst.content.beans.query.HstCtxWhereClauseComputer;
@@ -77,6 +78,7 @@
         return this.valueProvider;
     }
 
+    @IndexField // this is a mandatory field for indexing
     public String getName() {
         return valueProvider.getName();
     }
@@ -89,9 +91,16 @@
         return (valueProvider == null) ? null : valueProvider.getPath();
     }
 
+    @IndexField(name="id") // this is a mandatory field for indexing
+    String canonicalUUID;
+    
     @Override
     public String getCanonicalUUID() {
-        return getValueProvider().getIdentifier();
+        if(canonicalUUID != null) {
+            return canonicalUUID;
+        }
+        canonicalUUID = getValueProvider().getIdentifier();
+        return canonicalUUID;
     }
 
     @Override
Index: content-beans/pom.xml
===================================================================
--- content-beans/pom.xml	(revision 29199)
+++ content-beans/pom.xml	(working copy)
@@ -125,6 +125,17 @@
     
     <!-- Hst test dependencies -->
     
+    
+    <!-- SOLR  -->
+    <dependency>
+        <artifactId>solr-solrj</artifactId>
+        <groupId>org.apache.solr</groupId>
+        <version>1.4.1</version>
+        <!-- version>${solr-solrj.version}</version-->
+    </dependency>
+    
+    <!-- END SOLR  -->
+    
   </dependencies>
   
   <build>
Index: demosuite/site/src/main/webapp/WEB-INF/jsp/components/main/solr_search.jsp
===================================================================
--- demosuite/site/src/main/webapp/WEB-INF/jsp/components/main/solr_search.jsp	(revision 0)
+++ demosuite/site/src/main/webapp/WEB-INF/jsp/components/main/solr_search.jsp	(revision 0)
@@ -0,0 +1,48 @@
+<%--
+  Copyright 2009 Hippo
+
+  Licensed 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. 
+--%>
+<%@ page language="java" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x" %>
+<%@ taglib uri="http://www.hippoecm.org/jsp/hst/core" prefix='hst'%>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
+
+<div id="yui-u">
+   
+    <hst:link var="searchURL" path="/solrsearch" />
+    <form action="${searchURL}" method="get">
+      <div>
+        <input type="text" name="query" value="${query}"/>
+        <input type="submit" value="Search"/>
+      </div>
+    </form>
+    
+    <c:if test="${query != null && query != ''}">
+        
+          Results <b>${result.size}</b> for <b>${query}</b>.
+          
+          <c:forEach var="bean" items="${result.hstBeans}" varStatus="indexer">
+                              
+              <ul class="list-overview">
+                  <li class="title">
+                  ${bean} <br/>
+                  
+                      ${bean.name}
+                  </li>
+              </ul>
+          </c:forEach>
+           
+    </c:if>
+</div>
Index: demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/TextBean.java
===================================================================
--- demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/TextBean.java	(revision 29199)
+++ demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/TextBean.java	(working copy)
@@ -19,8 +19,9 @@
 import org.hippoecm.hst.content.beans.standard.HippoResource;
 
 @Node(jcrType="demosite:textdocument")
-public class TextBean extends BaseBean{
+public class TextBean extends BaseBean {
 
+    
 	// if you have in document resources
     public HippoResource getResource() {
         return getBean("demosite:hippo_resource");
Index: demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/solr/AgendaSolrBean.java
===================================================================
--- demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/solr/AgendaSolrBean.java	(revision 0)
+++ demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/solr/AgendaSolrBean.java	(revision 0)
@@ -0,0 +1,83 @@
+package org.hippoecm.hst.demo.beans.solr;
+
+import java.util.Calendar;
+import java.util.List;
+
+import org.hippoecm.hst.content.beans.HstBean;
+import org.hippoecm.hst.content.beans.index.IndexField;
+
+
+
+
+public class AgendaSolrBean implements HstBean {
+    @IndexField
+    private String id;
+    
+    @IndexField
+    private String name;
+
+    @IndexField
+    private String clazz = AgendaSolrBean.class.getName();
+
+    @IndexField
+    private String text = "Lorem ipsum agenda doc";
+    
+    @IndexField(name="cat")
+    private String[] categories;
+
+    @IndexField
+    private List<String> features;
+
+    @IndexField 
+    private Calendar date;
+
+    public String getCanonicalUUID() {
+        return id;
+    }
+
+    public void setCanonicalUUID(String id) {
+        this.id = id;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getClazz() {
+        return clazz;
+    }
+
+    public void setClazz(String clazz) {
+        this.clazz = clazz;
+    }
+
+    public String[] getCategories() {
+        return categories;
+    }
+
+    public void setCategories(String[] categories) {
+        this.categories = categories;
+    }
+
+    public List<String> getFeatures() {
+        return features;
+    }
+
+    public void setFeatures(List<String> features) {
+        this.features = features;
+    }
+
+    public Calendar getDate() {
+        return date;
+    }
+
+    public void setDate(Calendar date) {
+        this.date = date;
+    }
+
+    
+}
Index: demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/solr/TextSolrBean.java
===================================================================
--- demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/solr/TextSolrBean.java	(revision 0)
+++ demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/solr/TextSolrBean.java	(revision 0)
@@ -0,0 +1,68 @@
+package org.hippoecm.hst.demo.beans.solr;
+
+import java.util.List;
+
+import org.hippoecm.hst.content.beans.HstBean;
+import org.hippoecm.hst.content.beans.index.IndexField;
+
+public class TextSolrBean implements HstBean {
+  
+    @IndexField
+    private String id;
+
+    @IndexField
+    private String name;
+    
+    @IndexField
+    private String clazz = TextSolrBean.class.getName();
+    
+    @IndexField
+    private String text = "Lorem ipsum text doc";
+    
+    @IndexField(name="cat")
+    private String[] categories;
+
+    @IndexField
+    private List<String> features;
+
+    public String getCanonicalUUID() {
+        return id;
+    }
+
+    public void setCanonicalUUID(String id) {
+        this.id = id;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getClazz() {
+        return clazz;
+    }
+
+    public void setClazz(String clazz) {
+        this.clazz = clazz;
+    }
+
+    public String[] getCategories() {
+        return categories;
+    }
+
+    public void setCategories(String[] categories) {
+        this.categories = categories;
+    }
+
+    public List<String> getFeatures() {
+        return features;
+    }
+
+    public void setFeatures(List<String> features) {
+        this.features = features;
+    }
+
+}
Index: demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/NewsBean.java
===================================================================
--- demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/NewsBean.java	(revision 29199)
+++ demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/NewsBean.java	(working copy)
@@ -18,6 +18,7 @@
 import java.util.Calendar;
 
 import org.hippoecm.hst.content.beans.Node;
+import org.hippoecm.hst.content.beans.index.IndexField;
 import org.hippoecm.hst.content.beans.standard.HippoGalleryImageSetBean;
 
 @Node(jcrType="demosite:newsdocument")
@@ -25,10 +26,11 @@
 
     private HippoGalleryImageSetBean imageBean;
     private boolean imagesLoaded = false;
-    
+   
+   
     @Override
+    @IndexField
     public Calendar getDate() {
-        
         return getProperty("demosite:date");
     }
 
Index: demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/BaseBean.java
===================================================================
--- demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/BaseBean.java	(revision 29199)
+++ demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/BaseBean.java	(working copy)
@@ -22,6 +22,7 @@
 import org.hippoecm.hst.content.beans.ContentNodeBinder;
 import org.hippoecm.hst.content.beans.ContentNodeBindingException;
 import org.hippoecm.hst.content.beans.Node;
+import org.hippoecm.hst.content.beans.index.IndexField;
 import org.hippoecm.hst.content.beans.standard.HippoDocument;
 import org.hippoecm.hst.content.beans.standard.HippoGalleryImageSetBean;
 import org.hippoecm.hst.content.beans.standard.HippoHtml;
@@ -39,15 +40,17 @@
     
     protected final static String HTML_NODEPATH = "demosite:body";
     
+    @IndexField
     public String getTitle() {
         return title == null ? (String)getProperty("demosite:title"): title ;
     }
     
+    
     public void setTitle(String title) { 
         this.title = title;
     }
     
-   
+    @IndexField
     public String getSummary() {
         return summary == null ? (String)getProperty("demosite:summary"): summary ;
     }
Index: demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/ProductBean.java
===================================================================
--- demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/ProductBean.java	(revision 29199)
+++ demosuite/site/src/main/java/org/hippoecm/hst/demo/beans/ProductBean.java	(working copy)
@@ -15,40 +15,58 @@
  */
 package org.hippoecm.hst.demo.beans;
 
+import java.util.Calendar;
+
 import org.hippoecm.hst.content.beans.Node;
+import org.hippoecm.hst.content.beans.index.IndexField;
 import org.hippoecm.hst.content.beans.standard.HippoGalleryImageSetBean;
 
 @Node(jcrType="demosite:productdocument")
-public class ProductBean extends TextBean{
+public class ProductBean extends TextBean {
     
     private HippoGalleryImageSetBean imageBean;
     private boolean imagesLoaded = false;
     
+    @IndexField
     public String getTitle() {
         // product does not have a title
         return this.getLocalizedName();
     }
     
+    @IndexField
     public String getBrand(){
         return this.getProperty("demosite:brand");
     }
     
+    @IndexField
     public String getProduct(){
         return this.getProperty("demosite:product");
     }
     
+    @IndexField
     public String getColor(){
         return this.getProperty("demosite:color");
     }
     
+    @IndexField
     public String getType(){
         return this.getProperty("demosite:type");
     }
     
+    @IndexField
+    Double price;
+    
     public Double getPrice(){
         return this.getProperty("demosite:price");
     }
     
+    @IndexField
+    Calendar constructionDate;
+    
+    public Calendar getConstructionDate() {
+        return getProperty("demosite:constructiondate");
+    }
+    
     public String[] getTags(){
         return this.getProperty("hippostd:tags");
     }
Index: demosuite/site/src/main/java/org/hippoecm/hst/demo/components/AbstractSearchComponent.java
===================================================================
--- demosuite/site/src/main/java/org/hippoecm/hst/demo/components/AbstractSearchComponent.java	(revision 29199)
+++ demosuite/site/src/main/java/org/hippoecm/hst/demo/components/AbstractSearchComponent.java	(working copy)
@@ -51,7 +51,7 @@
 
 
     protected void doSearch(HstRequest request, HstResponse response, String query, String nodeType, String sortBy, int pageSize, HippoBean scope) {
-
+ 
         if (scope == null) {
             log.error("Scope for search is null.");
             request.setAttribute("searchResults", EMPTY_RESULTS);
@@ -79,6 +79,8 @@
                 hstQuery.addOrderByDescending(sortBy);
             }
             
+            hstQuery.setLimit(10);
+            
             if (query != null) {
                 Filter filter = hstQuery.createFilter();
                 filter.addContains(".", query);
Index: demosuite/site/src/main/java/org/hippoecm/hst/demo/components/LeftMenu.java
===================================================================
--- demosuite/site/src/main/java/org/hippoecm/hst/demo/components/LeftMenu.java	(revision 29199)
+++ demosuite/site/src/main/java/org/hippoecm/hst/demo/components/LeftMenu.java	(working copy)
@@ -31,7 +31,11 @@
     @Override
     public void doBeforeRender(HstRequest request, HstResponse response) throws HstComponentException {
         super.doBeforeRender(request, response);
-    
+      
+         
+        request.setAttribute("mounts" , request.getRequestContext().getVirtualHost().getVirtualHosts().getMountsByHostGroup("dev-test-many"));
+        request.setAttribute("doc", this.getContentBean(request));
+        
         HstSiteMenu menu = request.getRequestContext().getHstSiteMenus().getSiteMenu("main");
 
         EditableMenu editable = menu.getEditableMenu();
Index: demosuite/site/src/main/java/org/hippoecm/hst/demo/components/SolrSearch.java
===================================================================
--- demosuite/site/src/main/java/org/hippoecm/hst/demo/components/SolrSearch.java	(revision 0)
+++ demosuite/site/src/main/java/org/hippoecm/hst/demo/components/SolrSearch.java	(revision 0)
@@ -0,0 +1,301 @@
+/*
+ *  Copyright 2009 Hippo.
+ * 
+ *  Licensed 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 org.hippoecm.hst.demo.components;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Random;
+
+import javax.jcr.RepositoryException;
+import javax.servlet.ServletContext;
+
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.beans.DocumentObjectBinder;
+import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
+import org.hippoecm.hst.content.beans.HstBean;
+import org.hippoecm.hst.content.beans.ObjectBeanManagerException;
+import org.hippoecm.hst.content.beans.query.exceptions.QueryException;
+import org.hippoecm.hst.content.beans.solr.HstDocumentObjectBinder;
+import org.hippoecm.hst.content.beans.solr.HstSolrQuery;
+import org.hippoecm.hst.content.beans.solr.HstSolrQueryImpl;
+import org.hippoecm.hst.content.beans.solr.HstSolrQueryResult;
+import org.hippoecm.hst.content.beans.standard.HippoBean;
+import org.hippoecm.hst.content.beans.standard.HippoDocumentBean;
+import org.hippoecm.hst.content.beans.standard.HippoFolderBean;
+import org.hippoecm.hst.core.component.HstComponentException;
+import org.hippoecm.hst.core.component.HstRequest;
+import org.hippoecm.hst.core.component.HstResponse;
+import org.hippoecm.hst.core.request.ComponentConfiguration;
+import org.hippoecm.hst.demo.beans.NewsBean;
+import org.hippoecm.hst.demo.beans.ProductBean;
+import org.hippoecm.hst.demo.beans.solr.AgendaSolrBean;
+import org.hippoecm.hst.demo.beans.solr.TextSolrBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SolrSearch extends AbstractSearchComponent {
+
+    public static final Logger log = LoggerFactory.getLogger(SolrSearch.class);
+    
+    /*
+    CommonsHttpSolrServer is thread-safe and if you are using the following constructor,
+    you *MUST* re-use the same instance for all requests.  If instances are created on
+    the fly, it can cause a connection leak. The recommended practice is to keep a
+    static instance of CommonsHttpSolrServer per solr server url and share it for all requests.
+    See https://issues.apache.org/jira/browse/SOLR-861 for more details
+    */
+    
+    private static final String SOLR_URL = "http://localhost:8983/solr"; 
+    private SolrServer server;
+    
+    @Override
+    public void init(ServletContext servletContext, ComponentConfiguration componentConfig)
+            throws HstComponentException {
+        super.init(servletContext, componentConfig);
+        server = getSolrServer(); 
+    }
+
+    @Override
+    public void doAction(HstRequest request, HstResponse response) throws HstComponentException {
+        String query = request.getParameter("query");
+        response.setRenderParameter("query", query);
+    }
+     
+    @Override 
+    public void doBeforeRender(HstRequest request, HstResponse response) throws HstComponentException {
+        super.doBeforeRender(request, response);  
+        
+        if(getPublicRequestParameter(request, "populate") != null ) {
+            
+            server = getSolrServer(); 
+            
+            String populate = getPublicRequestParameter(request, "populate");
+            try {
+                int number = Integer.parseInt(populate);
+                populateRandom(number);
+            } catch (NumberFormatException e) {
+                // try to load some folder / document bean to send to solr
+                
+                populateRepoBeans(request, populate);
+            }
+            
+        }
+        
+        String query = getPublicRequestParameter(request, "query");
+        
+        if (query == null || "".equals(query)) {
+            query = request.getParameter("query");
+        }
+
+        if (query == null) {
+            return;
+        }
+         
+        request.setAttribute("query", query);
+        
+        try {
+            HstSolrQuery solrQuery = new HstSolrQueryImpl(request.getRequestContext().getSession(), server, query);
+            HstSolrQueryResult result = solrQuery.execute();
+            request.setAttribute("result", result);
+        } catch (RepositoryException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (QueryException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        
+    }
+
+    private void populateRepoBeans(HstRequest request, String path) {
+       HippoBean populate = this.getSiteContentBaseBean(request).getBean(path);
+        
+       try {
+        HippoBean canonical = (HippoBean)this.getObjectConverter().getObject(populate.getCanonicalUUID(), populate.getNode().getSession());
+
+        AutoBeanCommittingAndClearingList<HstBean> beans = new AutoBeanCommittingAndClearingList<HstBean>(2500, server);
+        long start = System.currentTimeMillis();
+        if(canonical instanceof HippoDocumentBean) {
+           populate((HippoDocumentBean)canonical, beans);   
+        } else {
+            populate((HippoFolderBean)canonical, beans);
+        }
+        beans.commit(); 
+       
+        System.out.println("Took "+(System.currentTimeMillis() - start)/1000+" seconds to populate " +beans.totalCommitted+" items.");
+       } catch (HstComponentException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ObjectBeanManagerException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (RepositoryException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+       
+    }
+    
+    
+    private class AutoBeanCommittingAndClearingList<E extends HstBean> extends ArrayList<E> {
+
+        private static final long serialVersionUID = 1L;
+        
+        private int limit;
+        private SolrServer server;
+        private int totalCommitted;
+        
+        AutoBeanCommittingAndClearingList(int limit, SolrServer server) {
+            this.limit = limit;
+            this.server = server;
+        }
+
+        @Override
+        public boolean add(E e) {
+            boolean b =  super.add(e);
+            ifFullCommit();
+            return b;
+        }
+
+        @Override
+        public void add(int index, E element) {
+           super.add(index, element);
+           ifFullCommit();
+        }
+
+        @Override
+        public boolean addAll(Collection<? extends E> c) {
+            boolean b =  super.addAll(c);
+            ifFullCommit();
+            return b;
+        }
+
+        @Override
+        public boolean addAll(int index, Collection<? extends E> c) {
+            boolean b =  super.addAll(index, c);
+            ifFullCommit();
+            return b;
+        }
+        
+        private void ifFullCommit() {
+            if(size() >= limit) {
+               commit(); 
+            }
+        }
+        
+        private void commit() { 
+            try {
+                server.addBeans(this);
+                server.commit();
+                totalCommitted += this.size();
+                System.out.println("totalCommitted = " + totalCommitted);
+                this.clear();
+            } catch (SolrServerException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+    }
+    
+    private void populate(HippoFolderBean folder, List<HstBean> beans) {
+       for(HippoFolderBean child: folder.getFolders()) {
+           populate(child, beans);
+       }
+       for(HippoDocumentBean doc : folder.getDocuments()) {
+           populate(doc, beans);
+       }
+    }
+
+    private void populate(HippoDocumentBean doc, List<HstBean> beans) {
+        if(doc instanceof NewsBean) {
+            beans.add(doc);
+        }
+        if(doc instanceof ProductBean) {
+            beans.add(doc);
+        }
+    }
+
+    private void populateRandom(int number) {
+        
+        List<HstBean> beans = new ArrayList<HstBean>();
+        Random rand = new Random();
+        for(int i = 0 ; i < number ; i ++) {
+            if(rand.nextInt(2) == 1) {
+                TextSolrBean item = new TextSolrBean();
+                item.setCanonicalUUID(System.currentTimeMillis() +  "-" + i);
+                item.setName("text bean " + item.getCanonicalUUID());
+                item.setCategories(new String[] { "aaa"+i, "bbb"+i, "ccc"+i });
+                beans.add(item);
+            } else {
+                AgendaSolrBean item = new AgendaSolrBean();
+                item.setCanonicalUUID(System.currentTimeMillis() +  "-" + i);
+                item.setName("agenda bean " + item.getCanonicalUUID());
+                item.setCategories(new String[] { "aaa"+i, "bbb"+i, "ccc"+i });
+                beans.add(item);
+            }
+        }
+        
+        try {
+            server.addBeans(beans);
+            server.commit();
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (SolrServerException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+    
+    private SolrServer getSolrServer() {
+        try {
+            server = new CommonsHttpSolrServer(SOLR_URL) {
+
+                private static final long serialVersionUID = 1L;
+
+                @Override
+                public DocumentObjectBinder getBinder() {
+                    return new HstDocumentObjectBinder();
+                }
+            };
+            server.deleteByQuery("*:*"); // delete everything!
+
+            
+            server.commit();
+
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (SolrServerException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        return server;
+    }
+
+}
Index: demosuite/pom.xml
===================================================================
--- demosuite/pom.xml	(revision 29199)
+++ demosuite/pom.xml	(working copy)
@@ -155,13 +155,13 @@
                   <cargo.jvmargs>
                     <![CDATA[-Xdebug -Xrunjdwp:transport=dt_socket,address=${cargo.debug.address},server=y,suspend=${cargo.debug.suspend} -noverify ${javaagent}]]>
                     <!-- for more memory -->
-                    <!-- 
-                    <![CDATA[-Xmx1024m ]]>
-                    -->
+                    
+                    <![CDATA[-Xmx1224m ]]>
+                    
                     <!-- for attaching a profiler like yourkit. Replace the agentpath with the correct path to libyjpagent.so -->
-                    <!--  
-                    <![CDATA[ -agentpath:/home/usr/Yourkit/yjp-9.0.8/bin/linux-x86-32/libyjpagent.so]]>
-                    -->
+                      
+                    <![CDATA[ -agentpath:/home/aschrijvers/Yourkit/yjp-9.0.8/bin/linux-x86-32/libyjpagent.so]]>
+                    
                   </cargo.jvmargs>
                 </properties>
                 <deployables>
Index: demosuite/content/src/main/resources/hstconfiguration/demosite/sitemenus.xml
===================================================================
--- demosuite/content/src/main/resources/hstconfiguration/demosite/sitemenus.xml	(revision 29199)
+++ demosuite/content/src/main/resources/hstconfiguration/demosite/sitemenus.xml	(working copy)
@@ -111,6 +111,14 @@
                 <sv:value>search</sv:value>
             </sv:property>
         </sv:node>
+        <sv:node sv:name="Solr Search">
+            <sv:property sv:name="jcr:primaryType" sv:type="Name">
+                <sv:value>hst:sitemenuitem</sv:value>
+            </sv:property>
+            <sv:property sv:name="hst:referencesitemapitem" sv:type="String">
+                <sv:value>solrsearch</sv:value>
+            </sv:property>
+        </sv:node>
         <sv:node sv:name="Form Component Example">
             <sv:property sv:name="jcr:primaryType" sv:type="Name">
                 <sv:value>hst:sitemenuitem</sv:value>
Index: demosuite/content/src/main/resources/hstconfiguration/demosite/sitemap.xml
===================================================================
--- demosuite/content/src/main/resources/hstconfiguration/demosite/sitemap.xml	(revision 29199)
+++ demosuite/content/src/main/resources/hstconfiguration/demosite/sitemap.xml	(working copy)
@@ -246,7 +246,15 @@
             <sv:value>hst:pages/searchpage</sv:value>
         </sv:property>
     </sv:node>
-   
+    <sv:node sv:name="solrsearch">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>hst:sitemapitem</sv:value>
+        </sv:property>
+        <sv:property sv:name="hst:componentconfigurationid" sv:type="String">
+            <sv:value>hst:pages/solrsearchpage</sv:value>
+        </sv:property>
+    </sv:node>
+    
     <sv:node sv:name="error">
         <sv:property sv:name="jcr:primaryType" sv:type="Name">
             <sv:value>hst:sitemapitem</sv:value>
Index: demosuite/content/src/main/resources/hstconfiguration/democommon/pages.xml
===================================================================
--- demosuite/content/src/main/resources/hstconfiguration/democommon/pages.xml	(revision 29199)
+++ demosuite/content/src/main/resources/hstconfiguration/democommon/pages.xml	(working copy)
@@ -101,22 +101,38 @@
 			</sv:property>
 		</sv:node>
 	</sv:node>
-	<sv:node sv:name="searchpage">
-		<sv:property sv:name="jcr:primaryType" sv:type="Name">
-			<sv:value>hst:component</sv:value>
-		</sv:property>
-		<sv:property sv:name="hst:referencecomponent" sv:type="String">
-			<sv:value>hst:pages/standard</sv:value>
-		</sv:property>
-		<sv:node sv:name="body">
-			<sv:property sv:name="jcr:primaryType" sv:type="Name">
-				<sv:value>hst:component</sv:value>
-			</sv:property>
-			<sv:property sv:name="hst:referencecomponent" sv:type="String">
-				<sv:value>hst:components/bodysearch</sv:value>
-			</sv:property>
-		</sv:node>
-	</sv:node>
+    <sv:node sv:name="searchpage">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>hst:component</sv:value>
+        </sv:property>
+        <sv:property sv:name="hst:referencecomponent" sv:type="String">
+            <sv:value>hst:pages/standard</sv:value>
+        </sv:property>
+        <sv:node sv:name="body">
+            <sv:property sv:name="jcr:primaryType" sv:type="Name">
+                <sv:value>hst:component</sv:value>
+            </sv:property>
+            <sv:property sv:name="hst:referencecomponent" sv:type="String">
+                <sv:value>hst:components/bodysearch</sv:value>
+            </sv:property>
+        </sv:node>
+    </sv:node>
+    <sv:node sv:name="solrsearchpage">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>hst:component</sv:value>
+        </sv:property>
+        <sv:property sv:name="hst:referencecomponent" sv:type="String">
+            <sv:value>hst:pages/standard</sv:value>
+        </sv:property>
+        <sv:node sv:name="body">
+            <sv:property sv:name="jcr:primaryType" sv:type="Name">
+                <sv:value>hst:component</sv:value>
+            </sv:property>
+            <sv:property sv:name="hst:referencecomponent" sv:type="String">
+                <sv:value>hst:components/bodysolrsearch</sv:value>
+            </sv:property>
+        </sv:node>
+    </sv:node>
 	<sv:node sv:name="faceted">
         <sv:property sv:name="jcr:primaryType" sv:type="Name">
             <sv:value>hst:component</sv:value>
Index: demosuite/content/src/main/resources/hstconfiguration/democommon/components.xml
===================================================================
--- demosuite/content/src/main/resources/hstconfiguration/democommon/components.xml	(revision 29199)
+++ demosuite/content/src/main/resources/hstconfiguration/democommon/components.xml	(working copy)
@@ -254,28 +254,47 @@
 		</sv:property>
 	</sv:node>
 	<sv:node sv:name="bodysearch">
-		<sv:property sv:name="jcr:primaryType" sv:type="Name">
-			<sv:value>hst:component</sv:value>
-		</sv:property>
-		<sv:property sv:name="hst:parameternames" sv:type="String"/>
-		<sv:property sv:name="hst:parametervalues" sv:type="String"/>
-		<sv:property sv:name="hst:referencecomponent" sv:type="String">
-			<sv:value>hst:components/general_threecolumnlayout</sv:value>
-		</sv:property>
-		<sv:node sv:name="content">
-			<sv:property sv:name="jcr:primaryType" sv:type="Name">
-				<sv:value>hst:component</sv:value>
-			</sv:property>
-			<sv:property sv:name="hst:componentclassname" sv:type="String">
-				<sv:value>org.hippoecm.hst.demo.components.Search</sv:value>
-			</sv:property>
-			<sv:property sv:name="hst:parameternames" sv:type="String"/>
-			<sv:property sv:name="hst:parametervalues" sv:type="String"/>
-			<sv:property sv:name="hst:template" sv:type="String">
-				<sv:value>searchresults</sv:value>
-			</sv:property>
-		</sv:node>
-	</sv:node>
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>hst:component</sv:value>
+        </sv:property>
+        <sv:property sv:name="hst:parameternames" sv:type="String"/>
+        <sv:property sv:name="hst:parametervalues" sv:type="String"/>
+        <sv:property sv:name="hst:referencecomponent" sv:type="String">
+            <sv:value>hst:components/general_threecolumnlayout</sv:value>
+        </sv:property>
+        <sv:node sv:name="content">
+            <sv:property sv:name="jcr:primaryType" sv:type="Name">
+                <sv:value>hst:component</sv:value>
+            </sv:property>
+            <sv:property sv:name="hst:componentclassname" sv:type="String">
+                <sv:value>org.hippoecm.hst.demo.components.Search</sv:value>
+            </sv:property>
+            <sv:property sv:name="hst:parameternames" sv:type="String"/>
+            <sv:property sv:name="hst:parametervalues" sv:type="String"/>
+            <sv:property sv:name="hst:template" sv:type="String">
+                <sv:value>searchresults</sv:value>
+            </sv:property>
+        </sv:node>
+    </sv:node>
+    <sv:node sv:name="bodysolrsearch">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>hst:component</sv:value>
+        </sv:property>
+        <sv:property sv:name="hst:referencecomponent" sv:type="String">
+            <sv:value>hst:components/general_threecolumnlayout</sv:value>
+        </sv:property>
+        <sv:node sv:name="content">
+            <sv:property sv:name="jcr:primaryType" sv:type="Name">
+                <sv:value>hst:component</sv:value>
+            </sv:property>
+            <sv:property sv:name="hst:componentclassname" sv:type="String">
+                <sv:value>org.hippoecm.hst.demo.components.SolrSearch</sv:value>
+            </sv:property>
+            <sv:property sv:name="hst:template" sv:type="String">
+                <sv:value>solrsearchresults</sv:value>
+            </sv:property>
+        </sv:node>
+    </sv:node>
     <sv:node sv:name="bodyfacetedaddproduct">
         <sv:property sv:name="jcr:primaryType" sv:type="Name">
             <sv:value>hst:component</sv:value>
Index: demosuite/content/src/main/resources/hstconfiguration/democommon/templates.xml
===================================================================
--- demosuite/content/src/main/resources/hstconfiguration/democommon/templates.xml	(revision 29199)
+++ demosuite/content/src/main/resources/hstconfiguration/democommon/templates.xml	(working copy)
@@ -160,15 +160,24 @@
 			<sv:value>jsp/templates/rss.jsp</sv:value>
 		</sv:property>
 	</sv:node>
-	<sv:node sv:name="searchresults">
-		<sv:property sv:name="jcr:primaryType" sv:type="Name">
-			<sv:value>hst:template</sv:value>
-		</sv:property>
-		<sv:property sv:name="hst:containers" sv:type="String"/>
-		<sv:property sv:name="hst:renderpath" sv:type="String">
-			<sv:value>jsp/components/main/search.jsp</sv:value>
-		</sv:property>
-	</sv:node>
+    <sv:node sv:name="searchresults">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>hst:template</sv:value>
+        </sv:property>
+        <sv:property sv:name="hst:containers" sv:type="String"/>
+        <sv:property sv:name="hst:renderpath" sv:type="String">
+            <sv:value>jsp/components/main/search.jsp</sv:value>
+        </sv:property>
+    </sv:node>
+    <sv:node sv:name="solrsearchresults">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>hst:template</sv:value>
+        </sv:property>
+        <sv:property sv:name="hst:containers" sv:type="String"/>
+        <sv:property sv:name="hst:renderpath" sv:type="String">
+            <sv:value>jsp/components/main/solr_search.jsp</sv:value>
+        </sv:property>
+    </sv:node>
     <sv:node sv:name="todolist">
         <sv:property sv:name="jcr:primaryType" sv:type="Name">
             <sv:value>hst:template</sv:value>
Index: api/src/main/java/org/hippoecm/hst/content/beans/HstBean.java
===================================================================
--- api/src/main/java/org/hippoecm/hst/content/beans/HstBean.java	(revision 0)
+++ api/src/main/java/org/hippoecm/hst/content/beans/HstBean.java	(revision 0)
@@ -0,0 +1,5 @@
+package org.hippoecm.hst.content.beans;
+
+public interface HstBean {
+
+}
Index: api/src/main/java/org/hippoecm/hst/content/beans/standard/HippoBean.java
===================================================================
--- api/src/main/java/org/hippoecm/hst/content/beans/standard/HippoBean.java	(revision 29199)
+++ api/src/main/java/org/hippoecm/hst/content/beans/standard/HippoBean.java	(working copy)
@@ -21,12 +21,13 @@
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
+import org.hippoecm.hst.content.beans.HstBean;
 import org.hippoecm.hst.content.beans.NodeAware;
 import org.hippoecm.hst.content.beans.manager.ObjectConverterAware;
 import org.hippoecm.hst.provider.jcr.JCRValueProvider;
 import org.hippoecm.repository.api.HippoNode;
 
-public interface HippoBean extends NodeAware, ObjectConverterAware, Comparable<HippoBean> {
+public interface HippoBean extends HstBean, NodeAware, ObjectConverterAware, Comparable<HippoBean> {
 
     /**
      * This returns the backing jcr node for this bean. 
Index: api/src/main/java/org/hippoecm/hst/content/beans/solr/HstBeanIterator.java
===================================================================
--- api/src/main/java/org/hippoecm/hst/content/beans/solr/HstBeanIterator.java	(revision 0)
+++ api/src/main/java/org/hippoecm/hst/content/beans/solr/HstBeanIterator.java	(revision 0)
@@ -0,0 +1,38 @@
+package org.hippoecm.hst.content.beans.solr;
+
+import java.util.Iterator;
+
+import org.hippoecm.hst.content.beans.HstBean;
+
+public interface HstBeanIterator<E> extends Iterator<HstBean>{
+
+    /**
+     * Skip a number of elements in the iterator. Using skip is very efficient when you know you want to have the, say, 100 to 110 
+     * beans, as the skip does not need to fetch number 1 to 100. 
+     *
+     * @param skipNum the non-negative number of elements to skip
+     * @throws java.util.NoSuchElementException
+     *          if skipped past the last element in the iterator.
+     */
+    void skip(int skipNum);
+
+    /**
+     * Returns the number of elements in the iterator.
+     * If this information is unavailable, returns -1.
+     *
+     * @return a long
+     */
+    int getSize();
+
+    /**
+     * Returns the current position within the iterator. The number
+     * returned is the 0-based index of the next element in the iterator,
+     * i.e. the one that will be returned on the subsequent <code>next</code> call.
+     * <p/>
+     * Note that this method does not check if there is a next element,
+     * i.e. an empty iterator will always return 0.
+     *
+     * @return a long
+     */
+    int getPosition();
+}
Index: api/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQuery.java
===================================================================
--- api/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQuery.java	(revision 0)
+++ api/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQuery.java	(revision 0)
@@ -0,0 +1,89 @@
+/*
+ *  Copyright 2008 Hippo.
+ * 
+ *  Licensed 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 org.hippoecm.hst.content.beans.solr;
+
+import org.hippoecm.hst.content.beans.query.exceptions.QueryException;
+import org.hippoecm.hst.content.beans.query.filter.BaseFilter;
+import org.hippoecm.hst.content.beans.query.filter.Filter;
+
+public interface HstSolrQuery {
+
+    /**
+     * The default limit that is used for a HstSolrQuery. Use {@link #setLimit(int)} if you need to override this value. 
+     */
+    final static int DEFAULT_LIMIT = 1000;
+    
+    void setFilter(BaseFilter filter);
+
+    BaseFilter getFilter();
+
+    /**
+     * 
+     * @return a new empty Filter
+     */
+    Filter createFilter();
+    
+    /**
+     * Sets the limit of search results.
+     * <b>Note</b> that setting this value very high might influence performance negatively
+     * @param limit
+     */
+    void setLimit(int limit);
+    
+    /**
+     * @return the query as string
+     * @throws QueryException if we cannot build the query string
+     */
+    String getQueryAsString() throws QueryException;
+    
+    /**
+     * Returns the limit of the HstQuery. If no limit is set, it returns the default HstQuery limit {@link #DEFAULT_LIMIT}
+     * @return the limit 
+     */
+    int getLimit();
+    
+    /**
+     * Sets the offset to start searching from. Default offset is <code>-1</code> which means it is ignored. A negative offset will be ignored
+     * @param offset
+     */
+    void setOffset(int offset);
+
+    /**
+     * Returns the offset of the HstQuery. If no offset is set through {@link #setOffset(int)}, the offset will be <code>-1</code> and will be ignored 
+     * @return the offset 
+     */
+    int getOffset();
+    
+    /**
+     * Order the object found (ascending)
+     * @param fieldNameAttribute the name of the field used to sort the search result
+     */
+    void addOrderByAscending(String fieldNameAttribute);
+
+    /**
+     * Order the object found (descending)
+     * @param fieldNameAttribute the name of the field used to sort the search result
+     */
+
+    void addOrderByDescending(String fieldNameAttribute);
+
+    /**
+     * The actual execution of the HstQuery. The HstQueryResult will never contain one and the same result twice. So, if a result matches
+     * the search criteria twice, it is still returned as one hit. 
+     * @return <code>{@link HstSolrQueryResult}</code>
+     */
+    HstSolrQueryResult execute() throws QueryException;
+}
Index: api/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQueryResult.java
===================================================================
--- api/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQueryResult.java	(revision 0)
+++ api/src/main/java/org/hippoecm/hst/content/beans/solr/HstSolrQueryResult.java	(revision 0)
@@ -0,0 +1,41 @@
+/*
+ *  Copyright 2008 Hippo.
+ * 
+ *  Licensed 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 org.hippoecm.hst.content.beans.solr;
+
+import org.hippoecm.hst.content.beans.HstBean;
+
+
+
+/**
+ * The result of the execution of the HstQuery. 
+ */
+public interface HstSolrQueryResult {
+    
+    /**
+     * @see #getTotalSize()
+     * @return the total number of authorized hits. 
+     */
+    int getSize();
+    
+    /** 
+     */
+    int getTotalSize();
+    
+    /**
+     * This returns the hits
+     */
+    HstBeanIterator<HstBean> getHstBeans();
+}
Index: api/src/main/java/org/hippoecm/hst/content/beans/index/IndexField.java
===================================================================
--- api/src/main/java/org/hippoecm/hst/content/beans/index/IndexField.java	(revision 0)
+++ api/src/main/java/org/hippoecm/hst/content/beans/index/IndexField.java	(revision 0)
@@ -0,0 +1,21 @@
+package org.hippoecm.hst.content.beans.index;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target( { ElementType.METHOD, ElementType.FIELD })
+@Documented
+public @interface IndexField {
+    
+    public static final String DEFAULT ="#default";
+    
+    /**
+     * @return Returns the field name. Defaults to the JavaBean property name.
+     */
+
+    String name() default DEFAULT;
+}

