diff --git a/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java b/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java
index a9eed77..9c7f616 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java
@@ -9,202 +9,350 @@
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.spans.SpanQuery;
 
-/** A base class for Spanqueries 
+/**
+ * A base class for Spanqueries. It added some properties and methods to the
+ * Lucene {@link SpanQuery} class.
  * 
- * 	@author margaretha
+ * The constructors of this class specify three kinds of spanqueries: <br/>
+ * <br/>
+ * 
+ * <ol>
+ * <li>Term span based queries are spanqueries retrieving spans based on a
+ * single sub/child spanquery. <br/>
+ * This kind of query is similar to the Lucene {@link SpanTermQuery}. It
+ * searches for term spans in an index and creates a span enumeration of them.
+ * Additionally, the retrieved spans contain some information related to the
+ * type of the term spans, or modified the term span positions.
+ * 
+ * For instance, a {@link SpanAttributeQuery} retrieves {@link AttributeSpans},
+ * which in addition to the Lucene SpanTermQuery properties, also have
+ * references to element or relation spans. <br/>
+ * <br/>
+ * </li>
+ * 
+ * <li>Spanqueries based on two sub/child spanqueries. <br/>
+ * These queries compare the positions or other properties of two sub
+ * spanqueries. Examples of such queries are distance-based queries calculating
+ * the distance between two sub/child spans. The resulting spans possibly
+ * stretch from the start position of a sub/child span to the end position of
+ * the other sub/child span. <br/>
+ * <br/>
+ * </li>
+ * 
+ * <li>Spanqueries comparing a sub/child spanquery to a list of spanqueries. <br/>
+ * An example of such queries is {@link SpanWithAttributeQuery} matching an
+ * {@link SpanElementQuery} and a list of SpanAttributeQueries. In other words,
+ * it retrieves {@link ElementSpans} having some specific attributes.<br/>
+ * <br/>
+ * </li>
+ * </ol>
+ * 
+ * @see SpanQuery
+ * 
+ * @author margaretha
  * */
-public abstract class SimpleSpanQuery extends SpanQuery 
-		implements Cloneable{		
-	
-	protected SpanQuery firstClause, secondClause;
-	protected List<SpanQuery> clauseList=null;
-	private String field;
-	protected boolean collectPayloads;
-    	
-	public SimpleSpanQuery(SpanQuery firstClause, boolean collectPayloads) {
-		if (firstClause == null){
-			throw new IllegalArgumentException("The first clause cannot be null.");
-		}
-    	this.field = firstClause.getField();
-    	this.setFirstClause(firstClause);
-    	this.collectPayloads = collectPayloads;
-	}  
-	
-    public SimpleSpanQuery(SpanQuery firstClause, SpanQuery secondClause, 
-    		boolean collectPayloads) {
-    	this(firstClause,collectPayloads);
-    	if (secondClause == null){
-			throw new IllegalArgumentException("The second clause cannot be null.");
-		}
-    	checkField(secondClause);
-    	this.setSecondClause(secondClause);  	
-	}
-    
-    public SimpleSpanQuery(SpanQuery firstClause, List<SpanQuery> 
-    		secondClauses, boolean collectPayloads) {
-    	this(firstClause,collectPayloads);
-    	
-		if (secondClauses == null){
-			throw new IllegalArgumentException("The list of second clauses cannot be null.");
-		}
-		if (secondClauses.size() < 1){
-			throw new IllegalArgumentException("The list of second clauses cannot be empty.");
-		}
-    	
-    	for (SpanQuery secondClause : secondClauses){
-    		if (secondClause == null){
-    			throw new IllegalArgumentException("A second clause cannot be null.");
-    		}
-	    	checkField(secondClause);
-		}
-    	this.setClauseList(secondClauses);
-	}
-    
-    private void checkField(SpanQuery clause) {
-    	if (!clause.getField().equals(field)){
-    		throw new IllegalArgumentException(
-    				"Clauses must have the same field.");
-    	}
-    }
-	
-	public List<SpanQuery> getClauseList() {
-		return clauseList;
-	}
+public abstract class SimpleSpanQuery extends SpanQuery implements Cloneable {
 
-	public void setClauseList(List<SpanQuery> clauseList) {
-		this.clauseList = clauseList;
-	}
+    protected SpanQuery firstClause, secondClause;
+    protected List<SpanQuery> clauseList = null;
+    private String field;
+    protected boolean collectPayloads;
 
-	@Override
-	public String getField() {
-		return field;
-	}
-	
-	public SpanQuery getFirstClause() {
-		return firstClause;
-	}
-
-	public void setFirstClause(SpanQuery firstClause) {
-		this.firstClause = firstClause;
-	}
-
-	public SpanQuery getSecondClause() {
-		return secondClause;
-	}
-
-	public void setSecondClause(SpanQuery secondClause) {
-		this.secondClause = secondClause;
-	}	
-		
-	public boolean isCollectPayloads() {
-		return collectPayloads;
-	}
-
-	public void setCollectPayloads(boolean collectPayloads) {
-		this.collectPayloads = collectPayloads;
-	}
-
-	// For rewriting fuzzy searches like wildcard and regex
-	@Override
-    public void extractTerms(Set<Term> terms) {
-		
-		if (terms == null){
-			throw new IllegalArgumentException("The term set cannot be null.");
-		}
-		
-		if (firstClause != null){
-			firstClause.extractTerms(terms);
-		}
-		
-		if (secondClause != null){
-			secondClause.extractTerms(terms);
-		}
-		else if (clauseList != null){
-			for (SpanQuery clause : clauseList){
-				clause.extractTerms(terms);
-			}
-		}			
-    };
-    
-	@Override
-	public Query rewrite(IndexReader reader) throws IOException {		
-		SimpleSpanQuery clone = null;
-		clone = updateClone(reader, clone, firstClause, 1);			
-		if (secondClause != null){
-		    clone = updateClone(reader, clone, secondClause, 2);			
-		}
-		else if (clauseList != null){
-			clone = updateClone(reader, clone, clauseList);
-		}
-		return (clone != null ? clone : this );		
-	}	
-	
-	private SimpleSpanQuery updateClone(IndexReader reader, SimpleSpanQuery clone, 
-			 List<SpanQuery> spanQueries) throws IOException{
-		
-		for (int i=0; i < spanQueries.size(); i++){
-			SpanQuery query = (SpanQuery) spanQueries.get(i).rewrite(reader);
-			if (!query.equals(spanQueries.get(i))) {
-				if (clone == null) clone = clone();
-				clone.getClauseList().set(i, query);
-			}
-		}
-		return clone;
-	}
-	
-	private SimpleSpanQuery updateClone(IndexReader reader, SimpleSpanQuery clone, 
-			 SpanQuery sq, int clauseNumber) throws IOException{
-		SpanQuery query = (SpanQuery) sq.rewrite(reader);
-		if (!query.equals(sq)) {
-			if (clone == null) clone = clone();
-			if (clauseNumber == 1) 
-				clone.firstClause = query;			
-			else clone.secondClause = query;
-		}
-		return clone;
-	}
-	
-    /** Used in rewriting query
+    /**
+     * Constructs a new SimpleSpanQuery using the specified {@link SpanQuery}
+     * and set whether payloads are to be collected or not.
+     * 
+     * @param firstClause a {@link SpanQuery}
+     * @param collectPayloads a boolean flag representing the value
+     *        <code>true</code> if payloads are to be collected, otherwise
+     *        <code>false</code>.
      * */
-	@Override
-    public boolean equals (Object o) {
-		if (this == o) return true;
-		if (getClass() != o.getClass()) return false;
-		
-		final SimpleSpanQuery q = (SimpleSpanQuery) o;
-		if (collectPayloads != q.collectPayloads) return false;
-		if (!firstClause.equals(q.firstClause)) return false;
-		if (secondClause != null && 
-				!secondClause.equals(q.secondClause)){ 
-			return false;
-		}
-		else if (clauseList != null){
-			for (int i=0; i < clauseList.size(); i++){
-				SpanQuery query = (SpanQuery) clauseList.get(i);
-				if (!query.equals(q.getClauseList().get(i))) {
-					return false;
-				}
-			}
-		}
-	
-		return true;
+    public SimpleSpanQuery(SpanQuery firstClause, boolean collectPayloads) {
+        if (firstClause == null) {
+            throw new IllegalArgumentException(
+                    "The first clause cannot be null.");
+        }
+        this.field = firstClause.getField();
+        this.setFirstClause(firstClause);
+        this.collectPayloads = collectPayloads;
+    }
+
+    /**
+     * Constructs a new SimpleSpanQuery using the specified spanqueries and set
+     * whether payloads are to be collected or not.
+     * 
+     * @param firstClause a {@link SpanQuery}
+     * @param secondClause a {@link SpanQuery}
+     * @param collectPayloads a boolean flag representing the value
+     *        <code>true</code> if payloads are to be collected, otherwise
+     *        <code>false</code>.
+     * */
+    public SimpleSpanQuery(SpanQuery firstClause, SpanQuery secondClause,
+            boolean collectPayloads) {
+        this(firstClause, collectPayloads);
+        if (secondClause == null) {
+            throw new IllegalArgumentException(
+                    "The second clause cannot be null.");
+        }
+        checkField(secondClause);
+        this.setSecondClause(secondClause);
+    }
+
+    /**
+     * Constructs a new SimpleSpanQuery using the spanqueries in the specified
+     * list and set whether payloads are to be collected or not.
+     * 
+     * @param firstClause a {@link SpanQuery}
+     * @param secondClauses a list of spanqueries
+     * @param collectPayloads a boolean flag representing the value
+     *        <code>true</code> if payloads are to be collected, otherwise
+     *        <code>false</code>.
+     * */
+    public SimpleSpanQuery(SpanQuery firstClause,
+            List<SpanQuery> secondClauses, boolean collectPayloads) {
+        this(firstClause, collectPayloads);
+
+        if (secondClauses == null) {
+            throw new IllegalArgumentException(
+                    "The list of second clauses cannot be null.");
+        }
+        if (secondClauses.size() < 1) {
+            throw new IllegalArgumentException(
+                    "The list of second clauses cannot be empty.");
+        }
+
+        for (SpanQuery secondClause : secondClauses) {
+            if (secondClause == null) {
+                throw new IllegalArgumentException(
+                        "A second clause cannot be null.");
+            }
+            checkField(secondClause);
+        }
+        this.setClauseList(secondClauses);
+    }
+
+    private void checkField(SpanQuery clause) {
+        if (!clause.getField().equals(field)) {
+            throw new IllegalArgumentException(
+                    "Clauses must have the same field.");
+        }
+    }
+
+    /**
+     * Returns a set of child spanqueries used in this query.
+     * 
+     * @return a list of spanqueries
+     */
+    public List<SpanQuery> getClauseList() {
+        return clauseList;
+    }
+
+    /**
+     * Sets a list of child spanqueries.
+     * 
+     * @param clauseList a list of spanqueries
+     */
+    public void setClauseList(List<SpanQuery> clauseList) {
+        this.clauseList = clauseList;
+    }
+
+    /**
+     * {@inheritDoc}
+     * */
+    @Override
+    public String getField() {
+        return field;
+    }
+
+    /**
+     * Returns the first child {@link SpanQuery}.
+     * 
+     * @return the first child {@link SpanQuery}.
+     */
+    public SpanQuery getFirstClause() {
+        return firstClause;
+    }
+
+    /**
+     * Sets the first child {@link SpanQuery}.
+     * 
+     * @param firstClause the first child {@link SpanQuery}.
+     */
+    public void setFirstClause(SpanQuery firstClause) {
+        this.firstClause = firstClause;
+    }
+
+    /**
+     * Returns the second child {@link SpanQuery}.
+     * 
+     * @return the second child {@link SpanQuery}.
+     */
+    public SpanQuery getSecondClause() {
+        return secondClause;
+    }
+
+    /**
+     * Sets the second child {@link SpanQuery}.
+     * 
+     * @param secondClause the second child {@link SpanQuery}.
+     */
+    public void setSecondClause(SpanQuery secondClause) {
+        this.secondClause = secondClause;
+    }
+
+    /**
+     * Tells if payloads are to be collected or not.
+     * 
+     * @return <code>true</code> if payloads are to be collected,
+     *         <code>false</code> otherwise.
+     */
+    public boolean isCollectPayloads() {
+        return collectPayloads;
+    }
+
+    /**
+     * Sets <code>true</code> if payloads are to be collected,
+     * <code>false</code> otherwise.
+     * 
+     * @param collectPayloads a boolean flag determining if payloads are to be
+     *        collected or not.
+     */
+    public void setCollectPayloads(boolean collectPayloads) {
+        this.collectPayloads = collectPayloads;
+    }
+
+    // For rewriting fuzzy searches like wildcard and regex
+    /** {@inheritDoc} */
+    @Override
+    public void extractTerms(Set<Term> terms) {
+
+        if (terms == null) {
+            throw new IllegalArgumentException("The term set cannot be null.");
+        }
+
+        if (firstClause != null) {
+            firstClause.extractTerms(terms);
+        }
+
+        if (secondClause != null) {
+            secondClause.extractTerms(terms);
+        } else if (clauseList != null) {
+            for (SpanQuery clause : clauseList) {
+                clause.extractTerms(terms);
+            }
+        }
     };
-    
+
+    /** {@inheritDoc} */
+    @Override
+    public Query rewrite(IndexReader reader) throws IOException {
+        SimpleSpanQuery clone = null;
+        clone = updateClone(reader, clone, firstClause, 1);
+        if (secondClause != null) {
+            clone = updateClone(reader, clone, secondClause, 2);
+        } else if (clauseList != null) {
+            clone = updateClone(reader, clone, clauseList);
+        }
+        return (clone != null ? clone : this);
+    }
+
+    /**
+     * Rewrites the spanqueries from the specified list, sets them to the clone,
+     * and return the clone.
+     * 
+     * @param reader
+     * @param clone
+     * @param spanQueries
+     * @return a SimpleSpanQuery
+     * @throws IOException
+     */
+    private SimpleSpanQuery updateClone(IndexReader reader,
+            SimpleSpanQuery clone, List<SpanQuery> spanQueries)
+            throws IOException {
+
+        for (int i = 0; i < spanQueries.size(); i++) {
+            SpanQuery query = (SpanQuery) spanQueries.get(i).rewrite(reader);
+            if (!query.equals(spanQueries.get(i))) {
+                if (clone == null)
+                    clone = clone();
+                clone.getClauseList().set(i, query);
+            }
+        }
+        return clone;
+    }
+
+    /**
+     * Rewrites the specified {@link SpanQuery} and sets it either as the first
+     * or the second child {@link SpanQuery} of the clone.
+     * 
+     * @param reader
+     * @param clone
+     * @param sq
+     * @param clauseNumber
+     * @return a SimpleSpanQuery
+     * @throws IOException
+     */
+    private SimpleSpanQuery updateClone(IndexReader reader,
+            SimpleSpanQuery clone, SpanQuery sq, int clauseNumber)
+            throws IOException {
+        SpanQuery query = (SpanQuery) sq.rewrite(reader);
+        if (!query.equals(sq)) {
+            if (clone == null)
+                clone = clone();
+            if (clauseNumber == 1)
+                clone.firstClause = query;
+            else
+                clone.secondClause = query;
+        }
+        return clone;
+    }
+
+    /**
+     * {@inheritDoc}
+     * */
+    // Used in rewriting query
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (getClass() != o.getClass())
+            return false;
+
+        final SimpleSpanQuery q = (SimpleSpanQuery) o;
+        if (collectPayloads != q.collectPayloads)
+            return false;
+        if (!firstClause.equals(q.firstClause))
+            return false;
+        if (secondClause != null && !secondClause.equals(q.secondClause)) {
+            return false;
+        } else if (clauseList != null) {
+            for (int i = 0; i < clauseList.size(); i++) {
+                SpanQuery query = (SpanQuery) clauseList.get(i);
+                if (!query.equals(q.getClauseList().get(i))) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    };
+
+    /** {@inheritDoc} */
+    @Override
     public int hashCode() {
-    	int hc = firstClause.hashCode();    	
-    	if (secondClause != null){
-    		hc += secondClause.hashCode();
-    	}    		
-    	else if (clauseList != null){
-    		for (int i=0; i < clauseList.size(); i++){
-				hc += clauseList.get(i).hashCode();
-			}
-    	}
-    	hc ^= (hc << 31) | (hc >>> 3);
-    	hc += Float.floatToRawIntBits(getBoost());
-    	return hc;
+        int hc = firstClause.hashCode();
+        if (secondClause != null) {
+            hc += secondClause.hashCode();
+        } else if (clauseList != null) {
+            for (int i = 0; i < clauseList.size(); i++) {
+                hc += clauseList.get(i).hashCode();
+            }
+        }
+        hc ^= (hc << 31) | (hc >>> 3);
+        hc += Float.floatToRawIntBits(getBoost());
+        return hc;
     };
-	
-	public abstract SimpleSpanQuery clone();	
-	
+
+    public abstract SimpleSpanQuery clone();
+
 }
