/**
 * 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.
 * 
 * Copyright 2012-2014 the original author or authors.
 */
package org.assertj.db.api;

import org.assertj.db.error.AssertJDBException;
import org.assertj.db.type.AbstractDbData;
import org.assertj.db.type.Column;
import org.assertj.db.type.Row;

/**
 * Abstract class that represents a assert with an origin assert (like {@link AbstractValueAssert} with
 * {@link AbstractSubAssert}).
 * 
 * @author Régis Pouiller
 * 
 * @param <E> The "self" type of this assertion class. Please read &quot;<a href="http://bit.ly/anMa4g"
 *          target="_blank">Emulating 'self types' using Java Generics to simplify fluent API implementation</a>&quot;
 *          for more details.
 * @param <O> The class of the assert of origin
 * @param <D> The class of the actual value (an sub-class of {@link AbstractDbData}).
 * @param <A> The class of the original assert (an sub-class of {@link AbstractDbAssert}).
 * @param <C> The class of this assert (an sub-class of {@link AbstractColumnAssert}).
 * @param <CV> The class of this assertion on the value (an sub-class of {@link AbstractColumnValueAssert}).
 * @param <R> The class of the equivalent row assert (an sub-class of {@link AbstractRowAssert}).
 * @param <RV> The class of the equivalent row assertion on the value (an sub-class of {@link AbstractRowValueAssert}).
 */
public abstract class AbstractAssertWithOriginAssert<E extends AbstractAssertWithOriginAssert<E, O, D, A, C, CV, R, RV>, O extends OriginAssert<D, A, C, CV, R, RV>, D extends AbstractDbData<D>, A extends AbstractDbAssert<D, A, C, CV, R, RV>, C extends AbstractColumnAssert<D, A, C, CV, R, RV>, CV extends AbstractColumnValueAssert<D, A, C, CV, R, RV>, R extends AbstractRowAssert<D, A, C, CV, R, RV>, RV extends AbstractRowValueAssert<D, A, C, CV, R, RV>>
    extends AbstractAssert<E> {

  /**
   * The origin assert.
   */
  private final O originAssert;

  /**
   * Constructor.
   * 
   * @param selfType Class of this assert : a sub-class of {@code AbstractAssert}.
   * @param originAssert The assert of origin.
   */
  AbstractAssertWithOriginAssert(Class<E> selfType, O originAssert) {
    super(selfType);
    this.originAssert = originAssert;
  }

  /**
   * Returns the assert of origin (an instance of a sub-class of {@link AbstractAssert}.
   * 
   * @return The assert of origin.
   */
  protected O returnToOriginAssert() {
    return originAssert;
  }

  /**
   * Returns assertion methods on the next {@link Row} in the list of {@link Row}.
   * 
   * @return An object to make assertions on the next {@link Row}.
   * @throws AssertJDBException If the {@code index} is out of the bounds.
   */
  public R row() {
    return returnToOriginAssert().row();
  }

  /**
   * Returns assertion methods on the {@link Row} at the {@code index} in parameter.
   * 
   * @param index The index corresponding to the {@link Row}.
   * @return An object to make assertions on the {@link Row}.
   * @throws AssertJDBException If the {@code index} is out of the bounds.
   */
  public R row(int index) {
    return returnToOriginAssert().row(index);
  }

  /**
   * Returns assertion methods on the next {@link Column} in the list of {@link Column}.
   * 
   * @return An object to make assertions on the next {@link Column}.
   * @throws AssertJDBException If the {@code index} is out of the bounds.
   */
  public C column() {
    return returnToOriginAssert().column();
  }

  /**
   * Returns assertion methods on the {@link Column} at the {@code index} in parameter.
   * 
   * @param index The index corresponding to the {@link Column}.
   * @return An object to make assertions on the {@link Column}.
   * @throws AssertJDBException If the {@code index} is out of the bounds.
   */
  public C column(int index) {
    return returnToOriginAssert().column(index);
  }

  /**
   * Returns assertion methods on the {@link Column} corresponding to the column name in parameter.
   * 
   * @param columnName The column name.
   * @return An object to make assertions on the {@link Column}.
   * @throws NullPointerException If the column name in parameter is null.
   * @throws AssertJDBException If there is no column with this name.
   */
  public C column(String columnName) {
    return returnToOriginAssert().column(columnName);
  }
}

@@ -659,142 +659,27 @@
 .db.
-error.AssertJDBException;%0Aimport org.assertj.db.type.AbstractDbData;%0Aimport org.assertj.db.type.Column;%0Aimport org.assertj.db.type.Row
+type.AbstractDbData
 ;%0A%0A/
@@ -2231,16 +2231,72 @@
 ssert%3CE%3E
+ implements AssertWithColumnsAndRows%3CD, A, C, CV, R, RV%3E
  %7B%0A%0A  /*
@@ -2880,245 +2880,37 @@
  /**
-%0A   * Returns assertion methods on the next
  %7B@
-l
 in
-k Row%7D in the list of %7B@link Row%7D.%0A   * %0A   * @return An object to make assertions on the next %7B@link Row%7D.%0A   * @throws AssertJDBException If the %7B@code index%7D is out of the bounds.%0A   */
+heritDoc%7D */%0A  @Override
 %0A  p
@@ -2980,304 +2980,37 @@
  /**
-%0A   * Returns assertion methods on the
  %7B@
-l
 in
-k Row%7D at the %7B@code index%7D in parameter.%0A   * %0A   * @param index The index corresponding to the %7B@link Row%7D.%0A   * @return An object to make assertions on the %7B@link Row%7D.%0A   * @throws AssertJDBException If the %7B@code index%7D is out of the bounds.%0A   */
+heritDoc%7D */%0A  @Override
 %0A  p
@@ -3094,254 +3094,37 @@
  /**
-%0A   * Returns assertion methods on the next
  %7B@
-l
 in
-k Column%7D in the list of %7B@link Column%7D.%0A   * %0A   * @return An object to make assertions on the next %7B@link Column%7D.%0A   * @throws AssertJDBException If the %7B@code index%7D is out of the bounds.%0A   */
+heritDoc%7D */%0A  @Override
 %0A  p
@@ -3200,313 +3200,37 @@
  /**
-%0A   * Returns assertion methods on the
  %7B@
-l
 in
-k Column%7D at the %7B@code index%7D in parameter.%0A   * %0A   * @param index The index corresponding to the %7B@link Column%7D.%0A   * @return An object to make assertions on the %7B@link Column%7D.%0A   * @throws AssertJDBException If the %7B@code index%7D is out of the bounds.%0A   */
+heritDoc%7D */%0A  @Override
 %0A  p
@@ -3320,370 +3320,37 @@
  /**
-%0A   * Returns assertion methods on the
  %7B@
-l
 in
-k Column%7D corresponding to the column name in parameter.%0A   * %0A   * @param columnName The column name.%0A   * @return An object to make assertions on the %7B@link Column%7D.%0A   * @throws NullPointerException If the column name in parameter is null.%0A   * @throws AssertJDBException If there is no column with this name.%0A   */
+heritDoc%7D */%0A  @Override
 %0A  p

Add AssertWithColumnsAndRows