/* This file is part of SableCC ( http://sablecc.org ).
 *
 * See the NOTICE file distributed with this work for copyright information.
 *
 * 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.sablecc.sablecc.automaton;

import org.sablecc.sablecc.alphabet.Symbol;
import org.sablecc.sablecc.exception.InternalException;

class Element<T extends Comparable<? super T>> {

    private final Partition<T> partition;

    private final DfaState<T> state;

    private Group<T> group;

    Element(
            final Partition<T> partition,
            final DfaState<T> state) {

        if (partition == null) {
            throw new InternalException("partition may not be null");
        }

        if (state == null) {
            throw new InternalException("state may not be null");
        }

        if (state.getDfa() != partition.getDfa()) {
            throw new InternalException("invalid state");
        }

        this.partition = partition;
        this.state = state;
        this.group = null;

        partition.addElement(this);
    }

    Partition<T> getPartition() {

        return this.partition;
    }

    DfaState<T> getState() {

        return this.state;
    }

    Group<T> getGroup() {

        return this.group;
    }

    void setGroup(
            Group<T> group) {

        if (group == null) {
            throw new InternalException("group may not be null");
        }

        if (group.getPartition() != this.partition) {
            throw new InternalException("invalid group");
        }

        // Don't forget that this.group is initially null!
        if (this.group != null) {
            this.group.removeElement(this);
        }

        this.group = group;
        group.addElement(this);
    }

    Group<T> getTarget(
            Symbol<T> symbol) {

        if (symbol == null) {
            throw new InternalException("symbol may not be null");
        }

        if (!this.partition.getDfa().getAlphabet().getSymbols()
                .contains(symbol)) {
            throw new InternalException("invalid symbol");
        }

        return this.partition.getElement(this.state.getTarget(symbol)).group;
    }
}

@@ -833,16 +833,143 @@
 ption;%0A%0A
+/**%0A * An element represents a state. It is especially used in methods related to%0A * transitions since they return groups.%0A */%0A
 class El
@@ -1006,24 +1006,66 @@
 uper T%3E%3E %7B%0A%0A
+    /** The partition of this element. */%0A
     private 
@@ -1103,70 +1103,558 @@
     
-private final DfaState%3CT%3E state;%0A%0A    private Group%3CT%3E group;%0A
+/** The state of this element. */%0A    private final DfaState%3CT%3E state;%0A%0A    /** The group of this element. */%0A    private Group%3CT%3E group;%0A%0A    /**%0A     * Constructs an element with the provided partition and state.%0A     * %0A     * @param partition%0A     *            the partition.%0A     * @param state%0A     *            the state.%0A     * @throws InternalException%0A     *             if the provided partition or state is %3Ccode%3Enull%3C/code%3E or%0A     *             if the state is not from same %3Ccode%3EDfa%3C/code%3E as the%0A     *             partition.%0A     */
 %0A   
@@ -2229,201 +2229,789 @@
     
-Partition%3CT%3E getPartition() %7B%0A%0A        return this.partition;%0A    %7D%0A%0A    DfaState%3CT%3E getState() %7B%0A%0A        return this.state;%0A    %7D%0A%0A    Group%3CT%3E getGroup() %7B%0A%0A        return this.group;%0A    %7D%0A
+/**%0A     * Returns the partition of this element.%0A     * %0A     * @return the partition.%0A     */%0A    Partition%3CT%3E getPartition() %7B%0A%0A        return this.partition;%0A    %7D%0A%0A    /**%0A     * Returns the state of this element.%0A     * %0A     * @return the state.%0A     */%0A    DfaState%3CT%3E getState() %7B%0A%0A        return this.state;%0A    %7D%0A%0A    /**%0A     * Returns the group of this element.%0A     * %0A     * @return the group.%0A     */%0A    Group%3CT%3E getGroup() %7B%0A%0A        return this.group;%0A    %7D%0A%0A    /**%0A     * Sets the group to wich this instance belongs.%0A     * %0A     * @param group%0A     *            the group.%0A     * @throws InternalException%0A     *             if the provided group is %3Ccode%3Enull%3C/code%3E or if it has a%0A     *             different partition as the one of this instance.%0A     */
 %0A   
@@ -3497,24 +3497,351 @@
 is);%0A    %7D%0A%0A
+    /**%0A     * Returns the target group of the provided symbol.%0A     * %0A     * @param symbol%0A     *            the symbol.%0A     * @return the target group.%0A     * @throws InternalException%0A     *             if the provided symbol is %3Ccode%3Enull%3C/code%3E or if it not%0A     *             part of this instance's partition.%0A     */%0A
     Group%3CT%3E

Add javadoc comments. See ticket:47.