/* Generated By:JavaCC: Do not edit this line. Parser.java */
package edu.stanford.smi.protege.storage.clips;

import java.util.*;
import java.util.logging.*;
import edu.stanford.smi.protege.model.*;
import edu.stanford.smi.protege.util.*;

public final class Parser implements ParserConstants {
    private KnowledgeBase itsKB;
    private Collection _itsErrors;
    private boolean isInclude;
    private Cls itsDefaultMetaCls;
    private Map itsInverseSlotMap = new HashMap();
    private Map itsSuperslotsMap = new HashMap();
    private Collection itsUndefinedClses = new HashSet();
    private Collection itsUndefinedInstances = new HashSet();
    private String state;
    private static final String LOADING_CLASSES = "loading classes";
    private static final String LOADING_INSTANCES = "loading instances";

    public String toString() {
        return "ClipsParser";
    }

    private void recordError(String msg) {
        recordError(msg, null);
    }

    private void recordError(String msg, Throwable e) {
        Object error = (e == null) ? (Object) msg : e;
        _itsErrors.add(error);
        Log.getLogger().log(Level.SEVERE, msg, e);
    }



    public void loadClses(KnowledgeBase kb, boolean isIncluded, Collection errors) {
        try {
            state = LOADING_CLASSES;
            itsKB = kb;
            itsDefaultMetaCls = kb.getCls(Model.Cls.STANDARD_CLASS);
            this.isInclude = isIncluded;
            _itsErrors = errors;
            parseOntology();
            connectInverseSlots();
            connectSuperslots();
            checkUndefinedClasses();
        } catch (Exception e) {
                recordError("Error parsing classes", e);
        }
    }

    private static final String UNDEFINED_CLASS = ":UNDEFINED";
    private Cls getUndefinedSuperclass() {
        Cls cls = itsKB.getCls(UNDEFINED_CLASS);
        if (cls == null) {
            Collection parents = CollectionUtilities.createCollection(itsKB.getRootCls());
            cls = itsKB.createCls(UNDEFINED_CLASS, parents);
        }
        return cls;
    }

    private void checkUndefinedClasses() {
        if (!itsUndefinedClses.isEmpty()) {
            Cls standardCls = itsKB.getDefaultClsMetaCls();
            Cls undefinedSuperclass = getUndefinedSuperclass();
            Iterator i = itsUndefinedClses.iterator();
            while (i.hasNext()) {
                Cls cls = (Cls) i.next();
                recordError("Undefined class: " + cls.getName() + " found while " + state);
                cls.addDirectSuperclass(undefinedSuperclass);
                cls.setDirectType(standardCls);
            }
            itsUndefinedClses.clear();
        }
    }

    private void checkUndefinedInstances() {
        if (!itsUndefinedInstances.isEmpty()) {
            Cls cls = getUndefinedSuperclass();
            Iterator i = itsUndefinedInstances.iterator();
            while (i.hasNext()) {
                Instance instance = (Instance) i.next();
                recordError("Undefined instance: " + instance.getName());
                instance.setDirectType(cls);
            }
        }
    }

    public void loadInstances(KnowledgeBase kb, boolean isIncluded, Collection errors) {
        try {
            state = LOADING_INSTANCES;
            itsKB = kb;
            this.isInclude = isIncluded;
            _itsErrors = errors;
                  parseKnowledgeBase();
            checkUndefinedClasses();
            checkUndefinedInstances();
        } catch (Exception e) {
                recordError("Error loading instances", e);
        }
    }

    private void handleException(Throwable e) {
        recordError("Parsing error", e);
        Token t;
        do {
            t = getNextToken();
        } while ((t.kind != EOF) && (t.kind != RPAREN && getToken(1).kind != LPAREN));
    }

    private void nameConflictError(String name, String typeName, Frame frame) {
        String text = name + " is both a " + typeName + " and a " + getTypeName(frame);
        recordError(text, null);
    }

    private String getTypeName(Frame frame) {
        String typeName;
        if (frame instanceof Cls) {
            typeName = "class";
        } else if (frame instanceof Slot) {
            typeName = "slot";
        } else if (frame instanceof Facet) {
            typeName = "facet";
        } else if (frame instanceof SimpleInstance) {
            typeName = "simple instance";
        } else {
            typeName = frame.getClass().getName();
        }
        return typeName;
    }

    private int nClses;
    private static int MIN_TRACE_COUNT = 5000;
    private static int TRACE_COUNT_DELTA = 1000;
    private static int MIN_CLASS_TRACE_COUNT = MIN_TRACE_COUNT;
    private static int MIN_INSTANCE_TRACE_COUNT = MIN_TRACE_COUNT;
    private static int CLASS_TRACE_COUNT_DELTA = TRACE_COUNT_DELTA;
    private static int INSTANCE_TRACE_COUNT_DELTA = TRACE_COUNT_DELTA;

    private Cls getCls(String name, String comment, Collection parents, boolean isDefinition) {
        if (name.equals(ClipsUtil.TOP_LEVEL_SLOT_CLASS)) {
            return null;
        }

        if (name.equals("USER")) {
            name = itsKB.getRootCls().getName();
        }

        Cls cls;
        Frame frame = itsKB.getFrame(name);
        if (frame == null) {
            cls = itsKB.createCls(name, parents, itsDefaultMetaCls, false);
            if ((++nClses % CLASS_TRACE_COUNT_DELTA) == 0 && nClses >= MIN_CLASS_TRACE_COUNT) {
                Log.getLogger().info("Loaded " + nClses + " classes: " + name);
            }
            if (comment != null) {
                cls.setDocumentation(comment);
            }
            if (!isDefinition) {
                itsUndefinedClses.add(cls);
            }
        } else if (frame instanceof Cls) {
            cls = (Cls) frame;
            if (isDefinition) {
                boolean succeeded = itsUndefinedClses.remove(cls);
                if (succeeded) {
                            if (comment != null) {
                                cls.setDocumentation(comment);
                            }
                            if (!parents.isEmpty()) {
                                addDirectSuperclasses(cls, parents);
                            }
                } else {
                    recordError("Duplicate definition of class " + name + " was ignored");
                }
            }
        } else if (frame instanceof SimpleInstance && ((Instance) frame).getDirectType() == null) {
            itsKB.setDirectType((Instance) frame, itsKB.getDefaultClsMetaCls());
            cls = itsKB.getCls(name);
            Iterator i = parents.iterator();
            while (i.hasNext()) {
                Cls parent = (Cls) i.next();
                cls.addDirectSuperclass(parent);
            }
        } else {
            nameConflictError(name, "class", frame);
            cls = getCls(name + "_", comment, parents, isDefinition);
        }
        if (isInclude) {
            cls.setIncluded(true);
        }
        return cls;
    }

    private void addDirectSuperclasses(Cls cls, Collection parents) {
        Iterator i = parents.iterator();
        while (i.hasNext()) {
            Cls parent = (Cls) i.next();
            cls.addDirectSuperclass(parent);
        }
    }

    private boolean hasSlot(String name) {
        return itsKB.containsFrame(name);
    }

    private Slot getExistingSlot(String name) {
        Slot slot;
        Frame frame = itsKB.getFrame(name);
        if (frame instanceof Slot) {
            slot = (Slot) frame;
        } else {
            recordError("non-existent slot: " + name);
            slot = getSlot(name);
        }
        return slot;
    }

    private Slot getSlot(String name) {
        Slot slot;
        Frame frame = itsKB.getFrame(name);
        if (frame == null) {
            slot = itsKB.createSlot(name, itsKB.getDefaultSlotMetaCls(), false);
        } else if (frame instanceof Slot) {
            slot = (Slot) frame;
        } else {
            nameConflictError(name, "slot", frame);
            slot = getSlot(name + "_");
        }
        if (isInclude) {
            slot.setIncluded(true);
        }
        return slot;
    }

    private int nInstances;
    private int nSetTypeInstances;
    private Instance getInstance(String instanceName, Collection types) {
        Instance instance = itsKB.getInstance(instanceName);
        if (instance == null) {
                Collection directTypes = types == null ? Collections.EMPTY_LIST : types;
            instance = itsKB.createInstance(new FrameID(instanceName), directTypes, false);
            if ((++nInstances % INSTANCE_TRACE_COUNT_DELTA) == 0 && nInstances >= MIN_INSTANCE_TRACE_COUNT) {
                Log.getLogger().info("Loaded " + nInstances + " instances: " + instanceName);
            }
            if (types == null) {
                itsUndefinedInstances.add(instance);
            }
            if (instance instanceof Cls) {
                itsUndefinedClses.add(instance);
            }
        } else if (types != null && !CollectionUtilities.equalsSet(instance.getDirectTypes(), types)) {
            if (isTypeMismatch(instance, types)) {
                recordError("type mismatch: " + instance + " cannot become an instance of " + types);
            }
            Instance oldInstance = instance;
            instance = instance.setDirectTypes(types);
            if ((++nSetTypeInstances % INSTANCE_TRACE_COUNT_DELTA) == 0 && nSetTypeInstances >= MIN_INSTANCE_TRACE_COUNT) {
                Log.getLogger().info("Set type on " + nSetTypeInstances + " instances: " + instanceName);
            }
            itsUndefinedInstances.remove(oldInstance);
        }
        if (isInclude) {
            instance.setIncluded(true);
        }
        return instance;
    }

    private static boolean isTypeMismatch(Instance instance, Collection types) {
        boolean isTypeMismatch;
        Cls cls = (Cls) CollectionUtilities.getFirstItem(types);
        if (instance instanceof Cls) {
            isTypeMismatch = !cls.isClsMetaCls();
        } else if (instance instanceof Slot) {
            isTypeMismatch = !cls.isSlotMetaCls();
        } else if (instance instanceof Facet) {
            isTypeMismatch = !cls.isFacetMetaCls();
        } else {
            isTypeMismatch = false;
        }
        return isTypeMismatch;
    }

    private void checkBooleanAndSetValues(Cls cls, Slot slot, Collection values) {
        if (areBooleanValues(values)) {
            if (cls == null) {
                Collection defaults = slot.getDefaultValues();
                defaults = convertToBooleanDefaults(defaults);
                slot.setValueType(ValueType.BOOLEAN);
                slot.setDefaultValues(defaults);
            } else {
                Collection defaults = cls.getTemplateSlotDefaultValues(slot);
                defaults = convertToBooleanDefaults(defaults);
                cls.setTemplateSlotValueType(slot, ValueType.BOOLEAN);
                cls.setTemplateSlotDefaultValues(slot, defaults);
            }
        } else {
            if (cls == null) {
                slot.setAllowedValues(values);
            } else {
                cls.setTemplateSlotAllowedValues(slot, values);
            }
        }
    }
        /*
    private void checkBoolean(Cls cls, Slot slot) {
        Collection values = (cls == null) ? slot.getAllowedValues() : cls.getTemplateSlotAllowedValues(slot);
        if (areBooleanValues(values)) {
            if (cls == null) {
                slot.setValueType(ValueType.BOOLEAN);
                Collection defaults = slot.getDefaultValues();
                defaults = convertToBooleanDefaults(defaults);
                slot.setDefaultValues(defaults);
            } else {
                cls.setTemplateSlotValueType(slot, ValueType.BOOLEAN);
                Collection defaults = cls.getTemplateSlotDefaultValues(slot);
                defaults = convertToBooleanDefaults(defaults);
                cls.setTemplateSlotDefaultValues(slot, defaults);
            }
        }
    }
    */

    private boolean areBooleanValues(Collection values) {
        boolean areBooleanValues = false;
        if (values.size() == 2) {
            Iterator i = values.iterator();
            String v1 = (String) i.next();
            if (isBooleanValue(v1)) {
                String v2 = (String) i.next();
                if (isBooleanValue(v2)) {
                    areBooleanValues = !v1.equalsIgnoreCase(v2);
                }
            }
        }
        return areBooleanValues;
    }

    private Collection convertToBooleanDefaults(Collection c) {
        Collection booleans;
        if (c.isEmpty()) {
            booleans = Collections.EMPTY_LIST;
        } else {
            booleans = new ArrayList();
            Iterator i = c.iterator();
            while (i.hasNext()) {
                Object o = i.next();
                booleans.add(Boolean.valueOf(o.toString()));
            }
        }
        return booleans;
    }

    private static boolean isBooleanValue(String s) {
        return s.equalsIgnoreCase("true") || s.equalsIgnoreCase("false");
    }

    private void checkedValueAdd(Collection values, ValueType type, Object value) {
        try {
            tryCheckedValueAdd(values, type, value);
        } catch (Exception e) {
            recordError("invalid object type", e);
        }
    }

    public static boolean equals(Object o1, Object o2) {
        return SystemUtilities.equals(o1, o2);
    }

    private void tryCheckedValueAdd(Collection values, ValueType type, Object value) {
        if (type == ValueType.CLS && value instanceof String) {
            value = getCls((String)value, null, Collections.EMPTY_LIST, false);
        } else if (type == ValueType.INSTANCE && value instanceof String) {
            value = getInstance((String)value, null);
        } else if (type == ValueType.FLOAT) {
            value = toFloat((String)value);
        } else if (type == ValueType.INTEGER) {
            value = toInteger((String)value);
        } else if (type == ValueType.BOOLEAN) {
            value = new Boolean((String)value);
        } else if (type == ValueType.ANY && value instanceof String) {
            // here we are essentially guessing
            Object first = CollectionUtilities.getFirstItem(values);
            if (first != null && appearsToBeValueType(values)) {
                value = getInstance((String) value, null);
            }
        }
        if (value == null) {
            throw new IllegalArgumentException("null value");
        }
        values.add(value);
    }

    private static boolean appearsToBeValueType(Collection values) {
        boolean isValueType = false;
        Object first = CollectionUtilities.getFirstItem(values);
        if (first != null) {
            isValueType = first.equals(ValueType.INSTANCE.toString()) || first.equals(ValueType.CLS.toString());
        }
        return isValueType;
    }

    Slot createTemplateSlot(String name, boolean isSingle, Cls cls, boolean isTopLevel) {
        Slot slot = getSlot(name);
        if (cls != null && !cls.hasTemplateSlot(slot)) {
            cls.addDirectTemplateSlot(slot);
        }
        if (!isSingle) {
            if (isTopLevel) {
                slot.setAllowsMultipleValues(true);
            } else {
                cls.setTemplateSlotAllowsMultipleValues(slot, true);
            }
        }
        return slot;
    }

    ValueType getSlotType(Cls cls, Slot slot) {
        return (cls == null) ? slot.getValueType() : cls.getTemplateSlotValueType(slot);
    }

    private static final String VARIABLE = "?VARIABLE";

    private Integer toInteger(String s) {
        Integer i = null;
        try {
            if (!s.equals(VARIABLE)) {
                i = new Integer(s);
            }
        } catch (Exception e) {
            try {
                Float f = new Float(s);
                i = new Integer(f.intValue());
            } catch (Exception e2) {
                recordError("Invalid integer: " + s, e2);
                i = null;
            }
        }
        return i;
    }

    private Float toFloat(String s) {
        Float f = null;
        try {
            if (!s.equals(VARIABLE)) {
                f = new Float(s);
            }
        } catch (Exception e) {
            recordError("Invalid floating point number: " + s, e);
            f = null;
        }
        return f;
    }

    private void addInverseSlotPair(Slot slot, Slot inverseSlot) {
        Slot existingSlot = (Slot) itsInverseSlotMap.get(inverseSlot);
        if (existingSlot == null) {
            itsInverseSlotMap.put(slot, inverseSlot);
        } else if (!equals(existingSlot, slot)) {
            recordError("mismatched inverse slots: " + slot + ", " + inverseSlot + ", " + existingSlot);
        } else {
            // do nothing
        }
    }

    private void addSuperslots(Slot slot, Collection superslots) {
        itsSuperslotsMap.put(slot, superslots);
    }

    private void connectInverseSlots() {
        Iterator i = itsInverseSlotMap.keySet().iterator();
        while (i.hasNext()) {
            Slot slot = (Slot) i.next();
            Slot inverseSlot = (Slot) itsInverseSlotMap.get(slot);
            slot.setInverseSlot(inverseSlot);
        }
    }

    private void connectSuperslots() {
        Iterator i = itsSuperslotsMap.keySet().iterator();
        while (i.hasNext()) {
            Slot slot = (Slot) i.next();
            Collection superslots = (Collection) itsSuperslotsMap.get(slot);
            connectSuperslots(slot, superslots);
        }
    }

    private void connectSuperslots(Slot slot, Collection superslots) {
        Iterator i = superslots.iterator();
        while (i.hasNext()) {
            String name = (String) i.next();
            Slot superslot = itsKB.getSlot(name);
            slot.addDirectSuperslot(superslot);
        }
    }

    private Facet getOrCreateFacet(String facetName) {
        Facet facet = itsKB.getFacet(facetName);
        if (facet == null) {
            facet = itsKB.createFacet(facetName, itsKB.getDefaultFacetMetaCls(), false);
        }
        return facet;
    }

    private Map clsToSlotToValueType = new HashMap();
    private ValueType getOwnSlotValueType(Instance instance, Collection directTypes, Slot slot) {
        ValueType valueType;
        if (directTypes.size() == 1) {
            Cls type = (Cls) CollectionUtilities.getFirstItem(directTypes);
            Map slotToValueType = (Map) clsToSlotToValueType.get(type);
            if (slotToValueType == null) {
                slotToValueType = new HashMap();
                clsToSlotToValueType.put(type, slotToValueType);
            }
            valueType = (ValueType) slotToValueType.get(slot);
            if (valueType == null) {
                valueType = instance.getOwnSlotValueType(slot);
                slotToValueType.put(slot, valueType);
            }
        } else {
            valueType = instance.getOwnSlotValueType(slot);
        }
        return valueType;
    }

// --------------------------------------------------------------------------------------
  final public void accessFacet(Cls cls, Slot slot) throws ParseException {
    jj_consume_token(ACCESS);
    switch (jj_nt.kind) {
    case READ_WRITE:
      jj_consume_token(READ_WRITE);
      break;
    case READ_ONLY:
      jj_consume_token(READ_ONLY);
      break;
    case INITIALIZER_ONLY:
      jj_consume_token(INITIALIZER_ONLY);
      break;
    default:
      jj_la1[0] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void allowedClassesValueDescription(Cls cls, Slot slot) throws ParseException {
    Collection clses;
    jj_consume_token(ALLOWED_CLASSES);
    clses = clsesList();
        if (cls == null) {
            slot.setAllowedClses(clses);
        } else {
            cls.setTemplateSlotAllowedClses(slot, clses);
        }
  }

  final public void allowedConstantValueDescription(Cls cls, Slot slot) throws ParseException {
    switch (jj_nt.kind) {
    case ALLOWED_FLOATS:
      allowedFloatsValueDescription(cls, slot);
      break;
    case ALLOWED_INTEGERS:
      allowedIntegersValueDescription(cls, slot);
      break;
    case ALLOWED_SYMBOLS:
      allowedSymbolsValueDescription(cls, slot);
      break;
    case ALLOWED_STRINGS:
      allowedStringsValueDescription(cls, slot);
      break;
    case ALLOWED_VALUES:
      allowedValuesValueDescription(cls, slot);
      break;
    default:
      jj_la1[1] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void allowedConstantValueDescriptionExtension(Cls cls, Slot slot) throws ParseException {
    switch (jj_nt.kind) {
    case ALLOWED_CLASSES:
      allowedClassesValueDescription(cls, slot);
      break;
    case ALLOWED_GRAMMAR:
      allowedGrammarValueDescription(cls, slot);
      break;
    case ALLOWED_PARENTS:
      allowedParentsValueDescription(cls, slot);
      break;
    default:
      jj_la1[2] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void allowedFloatsValueDescription(Cls cls, Slot slot) throws ParseException {
    String s;
    List list = new ArrayList();
    jj_consume_token(ALLOWED_FLOATS);
    label_1:
    while (true) {
      s = symbol();
                                  list.add(s);
      switch (jj_nt.kind) {
      case ABSTRACT:
      case ACCESS:
      case ALLOWED_CLASSES:
      case ALLOWED_FLOATS:
      case ALLOWED_GRAMMAR:
      case ALLOWED_INTEGERS:
      case ALLOWED_PARENTS:
      case ALLOWED_STRINGS:
      case ALLOWED_SYMBOLS:
      case ALLOWED_VALUES:
      case ANY:
      case ASSOCIATED_FACET:
      case BUILD:
      case CARDINALITY:
      case COMMENT:
      case COMPOSITE:
      case CONCRETE:
      case CREATE_ACCESSOR:
      case DEFAULT_:
      case DEFCLASS:
      case EXCLUSIVE:
      case FLOAT:
      case INCLUDE:
      case INHERIT:
      case INITIALIZER_ONLY:
      case INSTANCE:
      case INTEGER:
      case INVERSE_SLOT:
      case IS_A:
      case LOCAL:
      case MULTISLOT:
      case NO_INHERIT:
      case NON_REACTIVE:
      case NOTE:
      case OF:
      case OVERRIDE_MESSAGE:
      case PATTERN_MATCH:
      case PRIVATE:
      case PROPAGATION:
      case PUBLIC:
      case RANGE:
      case REACTIVE:
      case READ:
      case READ_ONLY:
      case READ_WRITE:
      case ROLE:
      case SINGLE_SLOT:
      case SHARED:
      case SLOT:
      case SOURCE:
      case STORAGE:
      case STRING:
      case SUBSLOT_OF:
      case SYMBOL:
      case TYPE:
      case USER_FACET:
      case VALUE:
      case VISIBILITY:
      case VERSION:
      case WRITE:
      case SYMBOL_LITERAL:
        ;
        break;
      default:
        jj_la1[3] = jj_gen;
        break label_1;
      }
    }
  }

  final public void allowedGrammarValueDescription(Cls cls, Slot slot) throws ParseException {
    jj_consume_token(ALLOWED_GRAMMAR);
    string();
    switch (jj_nt.kind) {
    case STRING_LITERAL:
      string();
      break;
    default:
      jj_la1[4] = jj_gen;
      ;
    }
  }

  final public void allowedIntegersValueDescription(Cls cls, Slot slot) throws ParseException {
    String s;
    List list = new ArrayList();
    jj_consume_token(ALLOWED_INTEGERS);
    label_2:
    while (true) {
      s = symbol();
                                    list.add(s);
      switch (jj_nt.kind) {
      case ABSTRACT:
      case ACCESS:
      case ALLOWED_CLASSES:
      case ALLOWED_FLOATS:
      case ALLOWED_GRAMMAR:
      case ALLOWED_INTEGERS:
      case ALLOWED_PARENTS:
      case ALLOWED_STRINGS:
      case ALLOWED_SYMBOLS:
      case ALLOWED_VALUES:
      case ANY:
      case ASSOCIATED_FACET:
      case BUILD:
      case CARDINALITY:
      case COMMENT:
      case COMPOSITE:
      case CONCRETE:
      case CREATE_ACCESSOR:
      case DEFAULT_:
      case DEFCLASS:
      case EXCLUSIVE:
      case FLOAT:
      case INCLUDE:
      case INHERIT:
      case INITIALIZER_ONLY:
      case INSTANCE:
      case INTEGER:
      case INVERSE_SLOT:
      case IS_A:
      case LOCAL:
      case MULTISLOT:
      case NO_INHERIT:
      case NON_REACTIVE:
      case NOTE:
      case OF:
      case OVERRIDE_MESSAGE:
      case PATTERN_MATCH:
      case PRIVATE:
      case PROPAGATION:
      case PUBLIC:
      case RANGE:
      case REACTIVE:
      case READ:
      case READ_ONLY:
      case READ_WRITE:
      case ROLE:
      case SINGLE_SLOT:
      case SHARED:
      case SLOT:
      case SOURCE:
      case STORAGE:
      case STRING:
      case SUBSLOT_OF:
      case SYMBOL:
      case TYPE:
      case USER_FACET:
      case VALUE:
      case VISIBILITY:
      case VERSION:
      case WRITE:
      case SYMBOL_LITERAL:
        ;
        break;
      default:
        jj_la1[5] = jj_gen;
        break label_2;
      }
    }
  }

  final public void allowedParentsValueDescription(Cls cls, Slot slot) throws ParseException {
    Collection parents;
    jj_consume_token(ALLOWED_PARENTS);
    parents = clsesList();
        if (cls == null) {
            slot.setAllowedParents(parents);
        } else {
            cls.setTemplateSlotAllowedParents(slot, parents);
        }
  }

  final public void allowedStringsValueDescription(Cls cls, Slot slot) throws ParseException {
    String s;
    List list = new ArrayList();
    jj_consume_token(ALLOWED_STRINGS);
    label_3:
    while (true) {
      s = string();
                                   list.add(s);
      switch (jj_nt.kind) {
      case STRING_LITERAL:
        ;
        break;
      default:
        jj_la1[6] = jj_gen;
        break label_3;
      }
    }
        if (cls == null) {
            slot.setAllowedValues(list);
        } else {
            cls.setTemplateSlotAllowedValues(slot, list);
        }
  }

  final public void allowedSymbolsValueDescription(Cls cls, Slot slot) throws ParseException {
    String s;
    List list = new ArrayList();
    jj_consume_token(ALLOWED_SYMBOLS);
    label_4:
    while (true) {
      s = symbol();
                                   list.add(s);
      switch (jj_nt.kind) {
      case ABSTRACT:
      case ACCESS:
      case ALLOWED_CLASSES:
      case ALLOWED_FLOATS:
      case ALLOWED_GRAMMAR:
      case ALLOWED_INTEGERS:
      case ALLOWED_PARENTS:
      case ALLOWED_STRINGS:
      case ALLOWED_SYMBOLS:
      case ALLOWED_VALUES:
      case ANY:
      case ASSOCIATED_FACET:
      case BUILD:
      case CARDINALITY:
      case COMMENT:
      case COMPOSITE:
      case CONCRETE:
      case CREATE_ACCESSOR:
      case DEFAULT_:
      case DEFCLASS:
      case EXCLUSIVE:
      case FLOAT:
      case INCLUDE:
      case INHERIT:
      case INITIALIZER_ONLY:
      case INSTANCE:
      case INTEGER:
      case INVERSE_SLOT:
      case IS_A:
      case LOCAL:
      case MULTISLOT:
      case NO_INHERIT:
      case NON_REACTIVE:
      case NOTE:
      case OF:
      case OVERRIDE_MESSAGE:
      case PATTERN_MATCH:
      case PRIVATE:
      case PROPAGATION:
      case PUBLIC:
      case RANGE:
      case REACTIVE:
      case READ:
      case READ_ONLY:
      case READ_WRITE:
      case ROLE:
      case SINGLE_SLOT:
      case SHARED:
      case SLOT:
      case SOURCE:
      case STORAGE:
      case STRING:
      case SUBSLOT_OF:
      case SYMBOL:
      case TYPE:
      case USER_FACET:
      case VALUE:
      case VISIBILITY:
      case VERSION:
      case WRITE:
      case SYMBOL_LITERAL:
        ;
        break;
      default:
        jj_la1[7] = jj_gen;
        break label_4;
      }
    }
        if (cls == null) {
            slot.setAllowedValues(list);
        } else {
            cls.setTemplateSlotAllowedValues(slot, list);
        }
  }

  final public void allowedValuesValueDescription(Cls cls, Slot slot) throws ParseException {
    List list;
    jj_consume_token(ALLOWED_VALUES);
    list = constants();
        checkBooleanAndSetValues(cls, slot, list);
  }

  final public void cardinalityValueDescription(Cls cls, Slot slot) throws ParseException {
    String minString;
    String maxString;
    jj_consume_token(CARDINALITY);
    minString = symbol();
    maxString = symbol();
        Integer min = toInteger(minString);
        if (min != null && min.intValue() != 0) {
            if (cls == null) {
                slot.setMinimumCardinality(min.intValue());
            } else {
                cls.setTemplateSlotMinimumCardinality(slot, min.intValue());
            }
        }
        Integer max = toInteger(maxString);
        if (max != null) {
            if (cls == null) {
                slot.setMaximumCardinality(max.intValue());
            } else {
                cls.setTemplateSlotMaximumCardinality(slot, max.intValue());
            }
        }
  }

  final public void cls() throws ParseException {
    Cls cls;
    String name;
    String comment = null;
    Collection parents;
    try {
      jj_consume_token(LPAREN);
      jj_consume_token(DEFCLASS);
      name = symbol();
      switch (jj_nt.kind) {
      case STRING_LITERAL:
        comment = string();
        break;
      default:
        jj_la1[8] = jj_gen;
        ;
      }
      jj_consume_token(LPAREN);
      jj_consume_token(IS_A);
      parents = clsesList();
      jj_consume_token(RPAREN);
            cls=getCls(name, comment, parents, true);
      clsRole(cls);
      label_5:
      while (true) {
        switch (jj_nt.kind) {
        case LPAREN:
          ;
          break;
        default:
          jj_la1[9] = jj_gen;
          break label_5;
        }
        slot(cls);
      }
      jj_consume_token(RPAREN);
    } catch (Exception e) {
        handleException(e);
    } catch (TokenMgrError e) {
        handleException(e);
    }
  }

  final public Cls clsReference() throws ParseException {
    String name;
    name = symbol();
        {if (true) return getCls(name, null, Collections.EMPTY_LIST, false);}
    throw new Error("Missing return statement in function");
  }

  final public List clsesList() throws ParseException {
    List clses = new ArrayList();
    Cls cls;
    label_6:
    while (true) {
      switch (jj_nt.kind) {
      case ABSTRACT:
      case ACCESS:
      case ALLOWED_CLASSES:
      case ALLOWED_FLOATS:
      case ALLOWED_GRAMMAR:
      case ALLOWED_INTEGERS:
      case ALLOWED_PARENTS:
      case ALLOWED_STRINGS:
      case ALLOWED_SYMBOLS:
      case ALLOWED_VALUES:
      case ANY:
      case ASSOCIATED_FACET:
      case BUILD:
      case CARDINALITY:
      case COMMENT:
      case COMPOSITE:
      case CONCRETE:
      case CREATE_ACCESSOR:
      case DEFAULT_:
      case DEFCLASS:
      case EXCLUSIVE:
      case FLOAT:
      case INCLUDE:
      case INHERIT:
      case INITIALIZER_ONLY:
      case INSTANCE:
      case INTEGER:
      case INVERSE_SLOT:
      case IS_A:
      case LOCAL:
      case MULTISLOT:
      case NO_INHERIT:
      case NON_REACTIVE:
      case NOTE:
      case OF:
      case OVERRIDE_MESSAGE:
      case PATTERN_MATCH:
      case PRIVATE:
      case PROPAGATION:
      case PUBLIC:
      case RANGE:
      case REACTIVE:
      case READ:
      case READ_ONLY:
      case READ_WRITE:
      case ROLE:
      case SINGLE_SLOT:
      case SHARED:
      case SLOT:
      case SOURCE:
      case STORAGE:
      case STRING:
      case SUBSLOT_OF:
      case SYMBOL:
      case TYPE:
      case USER_FACET:
      case VALUE:
      case VISIBILITY:
      case VERSION:
      case WRITE:
      case SYMBOL_LITERAL:
        ;
        break;
      default:
        jj_la1[10] = jj_gen;
        break label_6;
      }
      cls = clsReference();
                         clses.add(cls);
    }
        {if (true) return clses;}
    throw new Error("Missing return statement in function");
  }

  final public void clsRole(Cls cls) throws ParseException {
    boolean isAbstract;
    jj_consume_token(LPAREN);
    jj_consume_token(ROLE);
    switch (jj_nt.kind) {
    case CONCRETE:
      jj_consume_token(CONCRETE);
                                 isAbstract = false;
      break;
    case ABSTRACT:
      jj_consume_token(ABSTRACT);
                            isAbstract = true;
      break;
    default:
      jj_la1[11] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    jj_consume_token(RPAREN);
        if (cls != null) {
            cls.setAbstract(isAbstract);
        }
  }

  final public Object constant() throws ParseException {
    Object o;
    switch (jj_nt.kind) {
    case STRING_LITERAL:
      o = string();
      break;
    case ABSTRACT:
    case ACCESS:
    case ALLOWED_CLASSES:
    case ALLOWED_FLOATS:
    case ALLOWED_GRAMMAR:
    case ALLOWED_INTEGERS:
    case ALLOWED_PARENTS:
    case ALLOWED_STRINGS:
    case ALLOWED_SYMBOLS:
    case ALLOWED_VALUES:
    case ANY:
    case ASSOCIATED_FACET:
    case BUILD:
    case CARDINALITY:
    case COMMENT:
    case COMPOSITE:
    case CONCRETE:
    case CREATE_ACCESSOR:
    case DEFAULT_:
    case DEFCLASS:
    case EXCLUSIVE:
    case FLOAT:
    case INCLUDE:
    case INHERIT:
    case INITIALIZER_ONLY:
    case INSTANCE:
    case INTEGER:
    case INVERSE_SLOT:
    case IS_A:
    case LOCAL:
    case MULTISLOT:
    case NO_INHERIT:
    case NON_REACTIVE:
    case NOTE:
    case OF:
    case OVERRIDE_MESSAGE:
    case PATTERN_MATCH:
    case PRIVATE:
    case PROPAGATION:
    case PUBLIC:
    case RANGE:
    case REACTIVE:
    case READ:
    case READ_ONLY:
    case READ_WRITE:
    case ROLE:
    case SINGLE_SLOT:
    case SHARED:
    case SLOT:
    case SOURCE:
    case STORAGE:
    case STRING:
    case SUBSLOT_OF:
    case SYMBOL:
    case TYPE:
    case USER_FACET:
    case VALUE:
    case VISIBILITY:
    case VERSION:
    case WRITE:
    case SYMBOL_LITERAL:
      o = symbol();
      break;
    case INSTANCE_NAME_LITERAL:
      o = instanceReference();
      break;
    default:
      jj_la1[12] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
        {if (true) return o;}
    throw new Error("Missing return statement in function");
  }

  final public List constants() throws ParseException {
    Object value;
    List list = new ArrayList();
    label_7:
    while (true) {
      value = constant();
                         list.add(value);
      switch (jj_nt.kind) {
      case ABSTRACT:
      case ACCESS:
      case ALLOWED_CLASSES:
      case ALLOWED_FLOATS:
      case ALLOWED_GRAMMAR:
      case ALLOWED_INTEGERS:
      case ALLOWED_PARENTS:
      case ALLOWED_STRINGS:
      case ALLOWED_SYMBOLS:
      case ALLOWED_VALUES:
      case ANY:
      case ASSOCIATED_FACET:
      case BUILD:
      case CARDINALITY:
      case COMMENT:
      case COMPOSITE:
      case CONCRETE:
      case CREATE_ACCESSOR:
      case DEFAULT_:
      case DEFCLASS:
      case EXCLUSIVE:
      case FLOAT:
      case INCLUDE:
      case INHERIT:
      case INITIALIZER_ONLY:
      case INSTANCE:
      case INTEGER:
      case INVERSE_SLOT:
      case IS_A:
      case LOCAL:
      case MULTISLOT:
      case NO_INHERIT:
      case NON_REACTIVE:
      case NOTE:
      case OF:
      case OVERRIDE_MESSAGE:
      case PATTERN_MATCH:
      case PRIVATE:
      case PROPAGATION:
      case PUBLIC:
      case RANGE:
      case REACTIVE:
      case READ:
      case READ_ONLY:
      case READ_WRITE:
      case ROLE:
      case SINGLE_SLOT:
      case SHARED:
      case SLOT:
      case SOURCE:
      case STORAGE:
      case STRING:
      case SUBSLOT_OF:
      case SYMBOL:
      case TYPE:
      case USER_FACET:
      case VALUE:
      case VISIBILITY:
      case VERSION:
      case WRITE:
      case INSTANCE_NAME_LITERAL:
      case STRING_LITERAL:
      case SYMBOL_LITERAL:
        ;
        break;
      default:
        jj_la1[13] = jj_gen;
        break label_7;
      }
    }
        {if (true) return list;}
    throw new Error("Missing return statement in function");
  }

  final public void constraintValueDescription(Cls cls, Slot slot) throws ParseException {
    switch (jj_nt.kind) {
    case TYPE:
      typeValueDescription(cls, slot);
      break;
    case ALLOWED_FLOATS:
    case ALLOWED_INTEGERS:
    case ALLOWED_STRINGS:
    case ALLOWED_SYMBOLS:
    case ALLOWED_VALUES:
      allowedConstantValueDescription(cls, slot);
      break;
    case RANGE:
      rangeValueDescription(cls, slot);
      break;
    case CARDINALITY:
      cardinalityValueDescription(cls, slot);
      break;
    default:
      jj_la1[14] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void constraintValueDescriptionExtension(Cls cls, Slot slot) throws ParseException {
    allowedConstantValueDescriptionExtension(cls, slot);
  }

  final public void createAccessorFacet(Cls cls, Slot slot) throws ParseException {
    jj_consume_token(CREATE_ACCESSOR);
    switch (jj_nt.kind) {
    case QUESTION_NONE:
      jj_consume_token(QUESTION_NONE);
      break;
    case READ:
      jj_consume_token(READ);
      break;
    case WRITE:
      jj_consume_token(WRITE);
      break;
    case READ_WRITE:
      jj_consume_token(READ_WRITE);
      break;
    default:
      jj_la1[15] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }

  }

  final public void defaultFacet(Cls cls, Slot slot) throws ParseException {
    List list = new ArrayList();
    Object value;
    ValueType type = getSlotType(cls, slot);
    jj_consume_token(DEFAULT_);
    label_8:
    while (true) {
      value = constant();
                                  checkedValueAdd(list, type, value);
      switch (jj_nt.kind) {
      case ABSTRACT:
      case ACCESS:
      case ALLOWED_CLASSES:
      case ALLOWED_FLOATS:
      case ALLOWED_GRAMMAR:
      case ALLOWED_INTEGERS:
      case ALLOWED_PARENTS:
      case ALLOWED_STRINGS:
      case ALLOWED_SYMBOLS:
      case ALLOWED_VALUES:
      case ANY:
      case ASSOCIATED_FACET:
      case BUILD:
      case CARDINALITY:
      case COMMENT:
      case COMPOSITE:
      case CONCRETE:
      case CREATE_ACCESSOR:
      case DEFAULT_:
      case DEFCLASS:
      case EXCLUSIVE:
      case FLOAT:
      case INCLUDE:
      case INHERIT:
      case INITIALIZER_ONLY:
      case INSTANCE:
      case INTEGER:
      case INVERSE_SLOT:
      case IS_A:
      case LOCAL:
      case MULTISLOT:
      case NO_INHERIT:
      case NON_REACTIVE:
      case NOTE:
      case OF:
      case OVERRIDE_MESSAGE:
      case PATTERN_MATCH:
      case PRIVATE:
      case PROPAGATION:
      case PUBLIC:
      case RANGE:
      case REACTIVE:
      case READ:
      case READ_ONLY:
      case READ_WRITE:
      case ROLE:
      case SINGLE_SLOT:
      case SHARED:
      case SLOT:
      case SOURCE:
      case STORAGE:
      case STRING:
      case SUBSLOT_OF:
      case SYMBOL:
      case TYPE:
      case USER_FACET:
      case VALUE:
      case VISIBILITY:
      case VERSION:
      case WRITE:
      case INSTANCE_NAME_LITERAL:
      case STRING_LITERAL:
      case SYMBOL_LITERAL:
        ;
        break;
      default:
        jj_la1[16] = jj_gen;
        break label_8;
      }
    }
        if (cls == null) {
            slot.setDefaultValues(list);
        } else {
            cls.setTemplateSlotDefaultValues(slot, list);
        }
  }

  final public String facetName() throws ParseException {
    String name;
    name = symbol();
        {if (true) return name;}
    throw new Error("Missing return statement in function");
  }

  final public void userFacet(Cls cls, Slot slot) throws ParseException {
    List rawvalues = new ArrayList();
    String facetName;
    Object rawvalue;
    jj_consume_token(USER_FACET);
    facetName = facetName();
    label_9:
    while (true) {
      rawvalue = constant();
                                                             rawvalues.add(rawvalue);
      switch (jj_nt.kind) {
      case ABSTRACT:
      case ACCESS:
      case ALLOWED_CLASSES:
      case ALLOWED_FLOATS:
      case ALLOWED_GRAMMAR:
      case ALLOWED_INTEGERS:
      case ALLOWED_PARENTS:
      case ALLOWED_STRINGS:
      case ALLOWED_SYMBOLS:
      case ALLOWED_VALUES:
      case ANY:
      case ASSOCIATED_FACET:
      case BUILD:
      case CARDINALITY:
      case COMMENT:
      case COMPOSITE:
      case CONCRETE:
      case CREATE_ACCESSOR:
      case DEFAULT_:
      case DEFCLASS:
      case EXCLUSIVE:
      case FLOAT:
      case INCLUDE:
      case INHERIT:
      case INITIALIZER_ONLY:
      case INSTANCE:
      case INTEGER:
      case INVERSE_SLOT:
      case IS_A:
      case LOCAL:
      case MULTISLOT:
      case NO_INHERIT:
      case NON_REACTIVE:
      case NOTE:
      case OF:
      case OVERRIDE_MESSAGE:
      case PATTERN_MATCH:
      case PRIVATE:
      case PROPAGATION:
      case PUBLIC:
      case RANGE:
      case REACTIVE:
      case READ:
      case READ_ONLY:
      case READ_WRITE:
      case ROLE:
      case SINGLE_SLOT:
      case SHARED:
      case SLOT:
      case SOURCE:
      case STORAGE:
      case STRING:
      case SUBSLOT_OF:
      case SYMBOL:
      case TYPE:
      case USER_FACET:
      case VALUE:
      case VISIBILITY:
      case VERSION:
      case WRITE:
      case INSTANCE_NAME_LITERAL:
      case STRING_LITERAL:
      case SYMBOL_LITERAL:
        ;
        break;
      default:
        jj_la1[17] = jj_gen;
        break label_9;
      }
    }
        Facet facet = getOrCreateFacet(facetName);
        ValueType type = facet.getValueType();
        List values = new ArrayList();
        Iterator i = rawvalues.iterator();
        while (i.hasNext()) {
            Object value = i.next();
            checkedValueAdd(values, type, value);
        }
        if (cls != null) {
                cls.setTemplateFacetValues(slot, facet, values);
        }
  }

  final public void templateSlotValueFacet(Cls cls, Slot slot) throws ParseException {
    List list = new ArrayList();
    Object value;
    ValueType type = getSlotType(cls, slot);
    jj_consume_token(VALUE);
    label_10:
    while (true) {
      value = constant();
                               checkedValueAdd(list, type, value);
      switch (jj_nt.kind) {
      case ABSTRACT:
      case ACCESS:
      case ALLOWED_CLASSES:
      case ALLOWED_FLOATS:
      case ALLOWED_GRAMMAR:
      case ALLOWED_INTEGERS:
      case ALLOWED_PARENTS:
      case ALLOWED_STRINGS:
      case ALLOWED_SYMBOLS:
      case ALLOWED_VALUES:
      case ANY:
      case ASSOCIATED_FACET:
      case BUILD:
      case CARDINALITY:
      case COMMENT:
      case COMPOSITE:
      case CONCRETE:
      case CREATE_ACCESSOR:
      case DEFAULT_:
      case DEFCLASS:
      case EXCLUSIVE:
      case FLOAT:
      case INCLUDE:
      case INHERIT:
      case INITIALIZER_ONLY:
      case INSTANCE:
      case INTEGER:
      case INVERSE_SLOT:
      case IS_A:
      case LOCAL:
      case MULTISLOT:
      case NO_INHERIT:
      case NON_REACTIVE:
      case NOTE:
      case OF:
      case OVERRIDE_MESSAGE:
      case PATTERN_MATCH:
      case PRIVATE:
      case PROPAGATION:
      case PUBLIC:
      case RANGE:
      case REACTIVE:
      case READ:
      case READ_ONLY:
      case READ_WRITE:
      case ROLE:
      case SINGLE_SLOT:
      case SHARED:
      case SLOT:
      case SOURCE:
      case STORAGE:
      case STRING:
      case SUBSLOT_OF:
      case SYMBOL:
      case TYPE:
      case USER_FACET:
      case VALUE:
      case VISIBILITY:
      case VERSION:
      case WRITE:
      case INSTANCE_NAME_LITERAL:
      case STRING_LITERAL:
      case SYMBOL_LITERAL:
        ;
        break;
      default:
        jj_la1[18] = jj_gen;
        break label_10;
      }
    }
        if (cls == null) {
            slot.setValues(list);
        } else {
            cls.setTemplateSlotValues(slot, list);
        }
  }

  final public void facet(Cls cls, Slot slot) throws ParseException {
    switch (jj_nt.kind) {
    case DEFAULT_:
      defaultFacet(cls, slot);
      break;
    case STORAGE:
      storageFacet(cls, slot);
      break;
    case ACCESS:
      accessFacet(cls, slot);
      break;
    case USER_FACET:
      userFacet(cls, slot);
      break;
    case PROPAGATION:
      propagationFacet(cls, slot);
      break;
    case SOURCE:
      sourceFacet(cls, slot);
      break;
    case PATTERN_MATCH:
      patternMatchFacet(cls, slot);
      break;
    case VISIBILITY:
      visibilityFacet(cls, slot);
      break;
    case CREATE_ACCESSOR:
      createAccessorFacet(cls, slot);
      break;
    case OVERRIDE_MESSAGE:
      overrideMessageFacet(cls, slot);
      break;
    case ALLOWED_FLOATS:
    case ALLOWED_INTEGERS:
    case ALLOWED_STRINGS:
    case ALLOWED_SYMBOLS:
    case ALLOWED_VALUES:
    case CARDINALITY:
    case RANGE:
    case TYPE:
      constraintValueDescription(cls, slot);
      break;
    case COMMENT:
      slotDocumentationFacet(cls, slot);
      break;
    case INVERSE_SLOT:
      inverseSlotProperty(cls, slot);
      break;
    case VALUE:
      templateSlotValueFacet(cls, slot);
      break;
    case SUBSLOT_OF:
      superslotProperty(cls, slot);
      break;
    case ASSOCIATED_FACET:
      associatedFacet(cls, slot);
      break;
    case ALLOWED_CLASSES:
    case ALLOWED_GRAMMAR:
    case ALLOWED_PARENTS:
      constraintValueDescriptionExtension(cls, slot);
      break;
    default:
      jj_la1[19] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void facetStatement(Cls cls, Slot slot) throws ParseException {
    switch (jj_nt.kind) {
    case EXTENSION:
      jj_consume_token(EXTENSION);
      break;
    default:
      jj_la1[20] = jj_gen;
      ;
    }
    jj_consume_token(LPAREN);
    facet(cls, slot);
    jj_consume_token(RPAREN);
  }

  final public void includeOntologies() throws ParseException {
    String name;
    List list = new ArrayList();
    jj_consume_token(EXTENSION);
    jj_consume_token(LPAREN);
    jj_consume_token(INCLUDE);
    label_11:
    while (true) {
      switch (jj_nt.kind) {
      case STRING_LITERAL:
        ;
        break;
      default:
        jj_la1[21] = jj_gen;
        break label_11;
      }
      name = string();
                                                   list.add(name);
    }
    jj_consume_token(RPAREN);

  }

  final public void instance() throws ParseException {
    String instanceName;
    Cls type;
    Collection types = new ArrayList();
    Instance instance;
    try {
      jj_consume_token(LPAREN);
      instanceName = instanceName();
      jj_consume_token(OF);
      label_12:
      while (true) {
        type = clsReference();
                                                                        types.add(type);
        switch (jj_nt.kind) {
        case ABSTRACT:
        case ACCESS:
        case ALLOWED_CLASSES:
        case ALLOWED_FLOATS:
        case ALLOWED_GRAMMAR:
        case ALLOWED_INTEGERS:
        case ALLOWED_PARENTS:
        case ALLOWED_STRINGS:
        case ALLOWED_SYMBOLS:
        case ALLOWED_VALUES:
        case ANY:
        case ASSOCIATED_FACET:
        case BUILD:
        case CARDINALITY:
        case COMMENT:
        case COMPOSITE:
        case CONCRETE:
        case CREATE_ACCESSOR:
        case DEFAULT_:
        case DEFCLASS:
        case EXCLUSIVE:
        case FLOAT:
        case INCLUDE:
        case INHERIT:
        case INITIALIZER_ONLY:
        case INSTANCE:
        case INTEGER:
        case INVERSE_SLOT:
        case IS_A:
        case LOCAL:
        case MULTISLOT:
        case NO_INHERIT:
        case NON_REACTIVE:
        case NOTE:
        case OF:
        case OVERRIDE_MESSAGE:
        case PATTERN_MATCH:
        case PRIVATE:
        case PROPAGATION:
        case PUBLIC:
        case RANGE:
        case REACTIVE:
        case READ:
        case READ_ONLY:
        case READ_WRITE:
        case ROLE:
        case SINGLE_SLOT:
        case SHARED:
        case SLOT:
        case SOURCE:
        case STORAGE:
        case STRING:
        case SUBSLOT_OF:
        case SYMBOL:
        case TYPE:
        case USER_FACET:
        case VALUE:
        case VISIBILITY:
        case VERSION:
        case WRITE:
        case SYMBOL_LITERAL:
          ;
          break;
        default:
          jj_la1[22] = jj_gen;
          break label_12;
        }
      }
            instance=getInstance(instanceName, types);
      label_13:
      while (true) {
        switch (jj_nt.kind) {
        case LPAREN:
          ;
          break;
        default:
          jj_la1[23] = jj_gen;
          break label_13;
        }
        slotValue(instance, types);
      }
      jj_consume_token(RPAREN);
    } catch (Exception e) {
        handleException(e);
    } catch (TokenMgrError e) {
        handleException(e);
    }
  }

  final public String instanceName() throws ParseException {
    String name;
    Token t;
    t = jj_consume_token(INSTANCE_NAME_LITERAL);
        name = t.image;
        name = name.substring(1, name.length()-1);
        name = ClipsUtil.toInternalSymbol(name);
        {if (true) return name;}
    throw new Error("Missing return statement in function");
  }

  final public Instance instanceReference() throws ParseException {
    String name;
    name = instanceName();
        {if (true) return getInstance(name, null);}
    throw new Error("Missing return statement in function");
  }

  final public void oldStuff() throws ParseException {
    jj_consume_token(EXTENSION);
    string();
    jj_consume_token(EXTENSION);
    instanceName();

  }

  final public void overrideMessageFacet(Frame frame, Slot slot) throws ParseException {
    jj_consume_token(OVERRIDE_MESSAGE);
    switch (jj_nt.kind) {
    case QUESTION_DEFAULT:
      jj_consume_token(QUESTION_DEFAULT);
      break;
    case ABSTRACT:
    case ACCESS:
    case ALLOWED_CLASSES:
    case ALLOWED_FLOATS:
    case ALLOWED_GRAMMAR:
    case ALLOWED_INTEGERS:
    case ALLOWED_PARENTS:
    case ALLOWED_STRINGS:
    case ALLOWED_SYMBOLS:
    case ALLOWED_VALUES:
    case ANY:
    case ASSOCIATED_FACET:
    case BUILD:
    case CARDINALITY:
    case COMMENT:
    case COMPOSITE:
    case CONCRETE:
    case CREATE_ACCESSOR:
    case DEFAULT_:
    case DEFCLASS:
    case EXCLUSIVE:
    case FLOAT:
    case INCLUDE:
    case INHERIT:
    case INITIALIZER_ONLY:
    case INSTANCE:
    case INTEGER:
    case INVERSE_SLOT:
    case IS_A:
    case LOCAL:
    case MULTISLOT:
    case NO_INHERIT:
    case NON_REACTIVE:
    case NOTE:
    case OF:
    case OVERRIDE_MESSAGE:
    case PATTERN_MATCH:
    case PRIVATE:
    case PROPAGATION:
    case PUBLIC:
    case RANGE:
    case REACTIVE:
    case READ:
    case READ_ONLY:
    case READ_WRITE:
    case ROLE:
    case SINGLE_SLOT:
    case SHARED:
    case SLOT:
    case SOURCE:
    case STORAGE:
    case STRING:
    case SUBSLOT_OF:
    case SYMBOL:
    case TYPE:
    case USER_FACET:
    case VALUE:
    case VISIBILITY:
    case VERSION:
    case WRITE:
    case SYMBOL_LITERAL:
      symbol();
      break;
    default:
      jj_la1[24] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }

  }

  final public void versionInfo() throws ParseException {
    String version;
    String build;
    jj_consume_token(EXTENSION);
    jj_consume_token(LPAREN);
    jj_consume_token(VERSION);
    version = string();
    jj_consume_token(RPAREN);
    jj_consume_token(EXTENSION);
    jj_consume_token(LPAREN);
    jj_consume_token(BUILD);
    build = string();
    jj_consume_token(RPAREN);
    itsKB.setVersionString(version);
    itsKB.setBuildString(build);
  }

  final public void parseKnowledgeBase() throws ParseException {
    if (jj_2_1(3)) {
      oldStuff();
    } else {
      ;
    }
    switch (jj_nt.kind) {
    case EXTENSION:
      versionInfo();
      break;
    default:
      jj_la1[25] = jj_gen;
      ;
    }
    label_14:
    while (true) {
      switch (jj_nt.kind) {
      case LPAREN:
        ;
        break;
      default:
        jj_la1[26] = jj_gen;
        break label_14;
      }
      instance();
    }
    jj_consume_token(0);
  }

  final public void parseOntology() throws ParseException {
    if (jj_2_2(3)) {
      includeOntologies();
    } else {
      ;
    }
    switch (jj_nt.kind) {
    case EXTENSION:
      versionInfo();
      break;
    default:
      jj_la1[27] = jj_gen;
      ;
    }
    label_15:
    while (true) {
      switch (jj_nt.kind) {
      case LPAREN:
        ;
        break;
      default:
        jj_la1[28] = jj_gen;
        break label_15;
      }
      cls();
    }
    jj_consume_token(0);
  }

  final public void patternMatchFacet(Frame frame, Slot slot) throws ParseException {
    jj_consume_token(PATTERN_MATCH);
    switch (jj_nt.kind) {
    case REACTIVE:
      jj_consume_token(REACTIVE);
      break;
    case NON_REACTIVE:
      jj_consume_token(NON_REACTIVE);
      break;
    default:
      jj_la1[29] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }

  }

  final public void patternMatchRole(Frame frame, Slot slot) throws ParseException {
    jj_consume_token(LPAREN);
    jj_consume_token(PATTERN_MATCH);
    switch (jj_nt.kind) {
    case REACTIVE:
      jj_consume_token(REACTIVE);
      break;
    case NON_REACTIVE:
      jj_consume_token(NON_REACTIVE);
      break;
    default:
      jj_la1[30] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    jj_consume_token(RPAREN);

  }

  final public void propagationFacet(Frame frame, Slot slot) throws ParseException {
    jj_consume_token(PROPAGATION);
    switch (jj_nt.kind) {
    case INHERIT:
      jj_consume_token(INHERIT);
      break;
    case NO_INHERIT:
      jj_consume_token(NO_INHERIT);
      break;
    default:
      jj_la1[31] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }

  }

  final public void rangeValueDescription(Cls cls, Slot slot) throws ParseException {
    String min;
    String max;
    jj_consume_token(RANGE);
    min = symbol();
    max = symbol();
        Float minValue = toFloat(min);
        Float maxValue = toFloat(max);
        if (cls == null) {
            slot.setMinimumValue(minValue);
            slot.setMaximumValue(maxValue);
        } else {
            cls.setTemplateSlotMinimumValue(slot, minValue);
            cls.setTemplateSlotMaximumValue(slot, maxValue);
        }
  }

  final public void slot(Cls cls) throws ParseException {
    boolean isTopLevel;
    boolean isSingle;
    String name;
    Slot slot;
    try {
      jj_consume_token(LPAREN);
      isSingle = slotCardinality();
      name = slotName();
            isTopLevel = (cls == null) || !hasSlot(name);
            slot=createTemplateSlot(name, isSingle, cls, isTopLevel);
            if (isTopLevel) {
                cls = null;
            }
      label_16:
      while (true) {
        switch (jj_nt.kind) {
        case LPAREN:
        case EXTENSION:
          ;
          break;
        default:
          jj_la1[32] = jj_gen;
          break label_16;
        }
        facetStatement(cls, slot);
      }
      jj_consume_token(RPAREN);
    } catch (Exception e) {
        handleException(e);
    }
  }

  final public boolean slotCardinality() throws ParseException {
    boolean single = true;
    switch (jj_nt.kind) {
    case SLOT:
      jj_consume_token(SLOT);
      break;
    case SINGLE_SLOT:
      jj_consume_token(SINGLE_SLOT);
      break;
    case MULTISLOT:
      jj_consume_token(MULTISLOT);
                                           single=false;
      break;
    default:
      jj_la1[33] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
        {if (true) return single;}
    throw new Error("Missing return statement in function");
  }

  final public void slotDocumentationFacet(Cls cls, Slot slot) throws ParseException {
    String s;
    jj_consume_token(COMMENT);
    s = string();
        if (cls == null) {
            slot.setDocumentation(s);
        } else {
            cls.setTemplateSlotDocumentation(slot, s);
        }
  }

  final public void inverseSlotProperty(Cls cls, Slot slot) throws ParseException {
    String s;
    jj_consume_token(INVERSE_SLOT);
    s = slotName();
        Slot inverseSlot = getSlot(s);
        addInverseSlotPair(slot, inverseSlot);
  }

  final public void superslotProperty(Cls cls, Slot slot) throws ParseException {
    String s;
    Collection superslots = new ArrayList();
    jj_consume_token(SUBSLOT_OF);
    label_17:
    while (true) {
      switch (jj_nt.kind) {
      case ABSTRACT:
      case ACCESS:
      case ALLOWED_CLASSES:
      case ALLOWED_FLOATS:
      case ALLOWED_GRAMMAR:
      case ALLOWED_INTEGERS:
      case ALLOWED_PARENTS:
      case ALLOWED_STRINGS:
      case ALLOWED_SYMBOLS:
      case ALLOWED_VALUES:
      case ANY:
      case ASSOCIATED_FACET:
      case BUILD:
      case CARDINALITY:
      case COMMENT:
      case COMPOSITE:
      case CONCRETE:
      case CREATE_ACCESSOR:
      case DEFAULT_:
      case DEFCLASS:
      case EXCLUSIVE:
      case FLOAT:
      case INCLUDE:
      case INHERIT:
      case INITIALIZER_ONLY:
      case INSTANCE:
      case INTEGER:
      case INVERSE_SLOT:
      case IS_A:
      case LOCAL:
      case MULTISLOT:
      case NO_INHERIT:
      case NON_REACTIVE:
      case NOTE:
      case OF:
      case OVERRIDE_MESSAGE:
      case PATTERN_MATCH:
      case PRIVATE:
      case PROPAGATION:
      case PUBLIC:
      case RANGE:
      case REACTIVE:
      case READ:
      case READ_ONLY:
      case READ_WRITE:
      case ROLE:
      case SINGLE_SLOT:
      case SHARED:
      case SLOT:
      case SOURCE:
      case STORAGE:
      case STRING:
      case SUBSLOT_OF:
      case SYMBOL:
      case TYPE:
      case USER_FACET:
      case VALUE:
      case VISIBILITY:
      case VERSION:
      case WRITE:
      case SYMBOL_LITERAL:
        ;
        break;
      default:
        jj_la1[34] = jj_gen;
        break label_17;
      }
      s = slotName();
                                superslots.add(s);
    }
        addSuperslots(slot, superslots);
  }

  final public void associatedFacet(Cls cls, Slot slot) throws ParseException {
    String facetName;
    jj_consume_token(ASSOCIATED_FACET);
    facetName = facetName();
        Facet facet = getOrCreateFacet(facetName);
        slot.setAssociatedFacet(facet);
        facet.setAssociatedSlot(slot);
  }

  final public String slotName() throws ParseException {
    String s;
    s = symbol();
        if (s.equals("name_")) {
            s = "name";
        } else if (s.equals("is-a_")) {
            s = "is-a";
        } else if (s.charAt(0) == ':') {
            // hack for old tables project
            if (s.equals(":domain-value")
                    || s.equals(":range-value")
                    || s.equals(":entry-slot")
                    || s.equals(":domain-value-slots")
                    || s.equals(":range-value-slots")) {
                s = s.substring(1, s.length());
            }
        }
        {if (true) return s;}
    throw new Error("Missing return statement in function");
  }

  final public void slotValue(Instance instance, Collection directTypes) throws ParseException {
    String name;
    Collection values;
    Slot slot;
    ValueType valueType;
    jj_consume_token(LPAREN);
    name = slotName();
        slot=getExistingSlot(name);
        valueType = getOwnSlotValueType(instance, directTypes, slot);
    values = slotValueFields(instance, slot, valueType);
    jj_consume_token(RPAREN);
        if (slot == null) {
            recordError("value for unknown slot: " + name + " in instance " + instance);
        } else {
            instance.setOwnSlotValues(slot, values);
        }
  }

  final public Collection slotValueFields(Instance instance, Slot slot, ValueType type) throws ParseException {
    Collection values = new ArrayList();
    Object value;
    label_18:
    while (true) {
      switch (jj_nt.kind) {
      case ABSTRACT:
      case ACCESS:
      case ALLOWED_CLASSES:
      case ALLOWED_FLOATS:
      case ALLOWED_GRAMMAR:
      case ALLOWED_INTEGERS:
      case ALLOWED_PARENTS:
      case ALLOWED_STRINGS:
      case ALLOWED_SYMBOLS:
      case ALLOWED_VALUES:
      case ANY:
      case ASSOCIATED_FACET:
      case BUILD:
      case CARDINALITY:
      case COMMENT:
      case COMPOSITE:
      case CONCRETE:
      case CREATE_ACCESSOR:
      case DEFAULT_:
      case DEFCLASS:
      case EXCLUSIVE:
      case FLOAT:
      case INCLUDE:
      case INHERIT:
      case INITIALIZER_ONLY:
      case INSTANCE:
      case INTEGER:
      case INVERSE_SLOT:
      case IS_A:
      case LOCAL:
      case MULTISLOT:
      case NO_INHERIT:
      case NON_REACTIVE:
      case NOTE:
      case OF:
      case OVERRIDE_MESSAGE:
      case PATTERN_MATCH:
      case PRIVATE:
      case PROPAGATION:
      case PUBLIC:
      case RANGE:
      case REACTIVE:
      case READ:
      case READ_ONLY:
      case READ_WRITE:
      case ROLE:
      case SINGLE_SLOT:
      case SHARED:
      case SLOT:
      case SOURCE:
      case STORAGE:
      case STRING:
      case SUBSLOT_OF:
      case SYMBOL:
      case TYPE:
      case USER_FACET:
      case VALUE:
      case VISIBILITY:
      case VERSION:
      case WRITE:
      case INSTANCE_NAME_LITERAL:
      case STRING_LITERAL:
      case SYMBOL_LITERAL:
        ;
        break;
      default:
        jj_la1[35] = jj_gen;
        break label_18;
      }
      value = constant();
                        checkedValueAdd(values, type, value);
    }
        {if (true) return values;}
    throw new Error("Missing return statement in function");
  }

  final public void slotValueFieldProperty() throws ParseException {
    jj_consume_token(LPAREN);
    symbol();
    label_19:
    while (true) {
      switch (jj_nt.kind) {
      case ABSTRACT:
      case ACCESS:
      case ALLOWED_CLASSES:
      case ALLOWED_FLOATS:
      case ALLOWED_GRAMMAR:
      case ALLOWED_INTEGERS:
      case ALLOWED_PARENTS:
      case ALLOWED_STRINGS:
      case ALLOWED_SYMBOLS:
      case ALLOWED_VALUES:
      case ANY:
      case ASSOCIATED_FACET:
      case BUILD:
      case CARDINALITY:
      case COMMENT:
      case COMPOSITE:
      case CONCRETE:
      case CREATE_ACCESSOR:
      case DEFAULT_:
      case DEFCLASS:
      case EXCLUSIVE:
      case FLOAT:
      case INCLUDE:
      case INHERIT:
      case INITIALIZER_ONLY:
      case INSTANCE:
      case INTEGER:
      case INVERSE_SLOT:
      case IS_A:
      case LOCAL:
      case MULTISLOT:
      case NO_INHERIT:
      case NON_REACTIVE:
      case NOTE:
      case OF:
      case OVERRIDE_MESSAGE:
      case PATTERN_MATCH:
      case PRIVATE:
      case PROPAGATION:
      case PUBLIC:
      case RANGE:
      case REACTIVE:
      case READ:
      case READ_ONLY:
      case READ_WRITE:
      case ROLE:
      case SINGLE_SLOT:
      case SHARED:
      case SLOT:
      case SOURCE:
      case STORAGE:
      case STRING:
      case SUBSLOT_OF:
      case SYMBOL:
      case TYPE:
      case USER_FACET:
      case VALUE:
      case VISIBILITY:
      case VERSION:
      case WRITE:
      case INSTANCE_NAME_LITERAL:
      case STRING_LITERAL:
      case SYMBOL_LITERAL:
        ;
        break;
      default:
        jj_la1[36] = jj_gen;
        break label_19;
      }
      constant();
    }
    jj_consume_token(RPAREN);
  }

  final public void sourceFacet(Cls cls, Slot slot) throws ParseException {
    jj_consume_token(SOURCE);
    switch (jj_nt.kind) {
    case COMPOSITE:
      jj_consume_token(COMPOSITE);
      break;
    case EXCLUSIVE:
      jj_consume_token(EXCLUSIVE);
      break;
    default:
      jj_la1[37] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void storageFacet(Cls cls, Slot slot) throws ParseException {
    jj_consume_token(STORAGE);
    switch (jj_nt.kind) {
    case LOCAL:
      jj_consume_token(LOCAL);
      break;
    case SHARED:
      jj_consume_token(SHARED);
      break;
    default:
      jj_la1[38] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public String string() throws ParseException {
    Token t;
    t = jj_consume_token(STRING_LITERAL);
        {if (true) return ClipsUtil.toInternalString(t.image);}
    throw new Error("Missing return statement in function");
  }

  final public String symbol() throws ParseException {
    Token t;
    String s;
    switch (jj_nt.kind) {
    case SYMBOL_LITERAL:
      t = jj_consume_token(SYMBOL_LITERAL);
                         s=t.image;
      break;
    case ABSTRACT:
    case ACCESS:
    case ALLOWED_CLASSES:
    case ALLOWED_FLOATS:
    case ALLOWED_GRAMMAR:
    case ALLOWED_INTEGERS:
    case ALLOWED_PARENTS:
    case ALLOWED_STRINGS:
    case ALLOWED_SYMBOLS:
    case ALLOWED_VALUES:
    case ANY:
    case ASSOCIATED_FACET:
    case BUILD:
    case CARDINALITY:
    case COMMENT:
    case COMPOSITE:
    case CONCRETE:
    case CREATE_ACCESSOR:
    case DEFAULT_:
    case DEFCLASS:
    case EXCLUSIVE:
    case FLOAT:
    case INCLUDE:
    case INHERIT:
    case INITIALIZER_ONLY:
    case INSTANCE:
    case INTEGER:
    case INVERSE_SLOT:
    case IS_A:
    case LOCAL:
    case MULTISLOT:
    case NO_INHERIT:
    case NON_REACTIVE:
    case NOTE:
    case OF:
    case OVERRIDE_MESSAGE:
    case PATTERN_MATCH:
    case PRIVATE:
    case PROPAGATION:
    case PUBLIC:
    case RANGE:
    case REACTIVE:
    case READ:
    case READ_ONLY:
    case READ_WRITE:
    case ROLE:
    case SINGLE_SLOT:
    case SHARED:
    case SLOT:
    case SOURCE:
    case STORAGE:
    case STRING:
    case SUBSLOT_OF:
    case SYMBOL:
    case TYPE:
    case USER_FACET:
    case VALUE:
    case VISIBILITY:
    case VERSION:
    case WRITE:
      s = keyword();
      break;
    default:
      jj_la1[39] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
        {if (true) return ClipsUtil.toInternalSymbol(s);}
    throw new Error("Missing return statement in function");
  }

  final public void typeValueDescription(Cls cls, Slot slot) throws ParseException {
    ValueType type;
    jj_consume_token(TYPE);
    switch (jj_nt.kind) {
    case FLOAT:
      jj_consume_token(FLOAT);
                                    type=ValueType.FLOAT;
      break;
    case INSTANCE:
      jj_consume_token(INSTANCE);
                                 type=ValueType.INSTANCE;
      break;
    case INTEGER:
      jj_consume_token(INTEGER);
                          type=ValueType.INTEGER;
      break;
    case STRING:
      jj_consume_token(STRING);
                          type=ValueType.STRING;
      break;
    case SYMBOL:
      jj_consume_token(SYMBOL);
                          type=ValueType.SYMBOL;
      break;
    case ANY:
      jj_consume_token(ANY);
                                            type=ValueType.ANY;
      break;
    default:
      jj_la1[40] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
        if (cls == null) {
            if (slot.getValueType() != type) {
                slot.setValueType(type);
            }
        } else {
            if (cls.getTemplateSlotValueType(slot) != type) {
                cls.setTemplateSlotValueType(slot, type);
            }
        }
  }

  final public void visibilityFacet(Cls cls, Slot slot) throws ParseException {
    jj_consume_token(VISIBILITY);
    switch (jj_nt.kind) {
    case PUBLIC:
      jj_consume_token(PUBLIC);
      break;
    case PRIVATE:
      jj_consume_token(PRIVATE);
      break;
    default:
      jj_la1[41] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public String keyword() throws ParseException {
    Token t;
    switch (jj_nt.kind) {
    case ABSTRACT:
      t = jj_consume_token(ABSTRACT);
      break;
    case ACCESS:
      t = jj_consume_token(ACCESS);
      break;
    case ASSOCIATED_FACET:
      t = jj_consume_token(ASSOCIATED_FACET);
      break;
    case ALLOWED_CLASSES:
      t = jj_consume_token(ALLOWED_CLASSES);
      break;
    case ALLOWED_FLOATS:
      t = jj_consume_token(ALLOWED_FLOATS);
      break;
    case ALLOWED_GRAMMAR:
      t = jj_consume_token(ALLOWED_GRAMMAR);
      break;
    case ALLOWED_PARENTS:
      t = jj_consume_token(ALLOWED_PARENTS);
      break;
    case ALLOWED_INTEGERS:
      t = jj_consume_token(ALLOWED_INTEGERS);
      break;
    case ALLOWED_STRINGS:
      t = jj_consume_token(ALLOWED_STRINGS);
      break;
    case ALLOWED_SYMBOLS:
      t = jj_consume_token(ALLOWED_SYMBOLS);
      break;
    case ALLOWED_VALUES:
      t = jj_consume_token(ALLOWED_VALUES);
      break;
    case ANY:
      t = jj_consume_token(ANY);
      break;
    case BUILD:
      t = jj_consume_token(BUILD);
      break;
    case CARDINALITY:
      t = jj_consume_token(CARDINALITY);
      break;
    case COMMENT:
      t = jj_consume_token(COMMENT);
      break;
    case COMPOSITE:
      t = jj_consume_token(COMPOSITE);
      break;
    case CONCRETE:
      t = jj_consume_token(CONCRETE);
      break;
    case CREATE_ACCESSOR:
      t = jj_consume_token(CREATE_ACCESSOR);
      break;
    case DEFAULT_:
      t = jj_consume_token(DEFAULT_);
      break;
    case DEFCLASS:
      t = jj_consume_token(DEFCLASS);
      break;
    case EXCLUSIVE:
      t = jj_consume_token(EXCLUSIVE);
      break;
    case FLOAT:
      t = jj_consume_token(FLOAT);
      break;
    case INCLUDE:
      t = jj_consume_token(INCLUDE);
      break;
    case INHERIT:
      t = jj_consume_token(INHERIT);
      break;
    case INITIALIZER_ONLY:
      t = jj_consume_token(INITIALIZER_ONLY);
      break;
    case INSTANCE:
      t = jj_consume_token(INSTANCE);
      break;
    case INTEGER:
      t = jj_consume_token(INTEGER);
      break;
    case INVERSE_SLOT:
      t = jj_consume_token(INVERSE_SLOT);
      break;
    case IS_A:
      t = jj_consume_token(IS_A);
      break;
    case LOCAL:
      t = jj_consume_token(LOCAL);
      break;
    case MULTISLOT:
      t = jj_consume_token(MULTISLOT);
      break;
    case NO_INHERIT:
      t = jj_consume_token(NO_INHERIT);
      break;
    case NON_REACTIVE:
      t = jj_consume_token(NON_REACTIVE);
      break;
    case NOTE:
      t = jj_consume_token(NOTE);
      break;
    case OF:
      t = jj_consume_token(OF);
      break;
    case OVERRIDE_MESSAGE:
      t = jj_consume_token(OVERRIDE_MESSAGE);
      break;
    case PATTERN_MATCH:
      t = jj_consume_token(PATTERN_MATCH);
      break;
    case PRIVATE:
      t = jj_consume_token(PRIVATE);
      break;
    case PROPAGATION:
      t = jj_consume_token(PROPAGATION);
      break;
    case PUBLIC:
      t = jj_consume_token(PUBLIC);
      break;
    case RANGE:
      t = jj_consume_token(RANGE);
      break;
    case REACTIVE:
      t = jj_consume_token(REACTIVE);
      break;
    case READ:
      t = jj_consume_token(READ);
      break;
    case READ_ONLY:
      t = jj_consume_token(READ_ONLY);
      break;
    case READ_WRITE:
      t = jj_consume_token(READ_WRITE);
      break;
    case ROLE:
      t = jj_consume_token(ROLE);
      break;
    case SINGLE_SLOT:
      t = jj_consume_token(SINGLE_SLOT);
      break;
    case SHARED:
      t = jj_consume_token(SHARED);
      break;
    case SLOT:
      t = jj_consume_token(SLOT);
      break;
    case SOURCE:
      t = jj_consume_token(SOURCE);
      break;
    case STORAGE:
      t = jj_consume_token(STORAGE);
      break;
    case STRING:
      t = jj_consume_token(STRING);
      break;
    case SUBSLOT_OF:
      t = jj_consume_token(SUBSLOT_OF);
      break;
    case SYMBOL:
      t = jj_consume_token(SYMBOL);
      break;
    case TYPE:
      t = jj_consume_token(TYPE);
      break;
    case USER_FACET:
      t = jj_consume_token(USER_FACET);
      break;
    case VALUE:
      t = jj_consume_token(VALUE);
      break;
    case VERSION:
      t = jj_consume_token(VERSION);
      break;
    case VISIBILITY:
      t = jj_consume_token(VISIBILITY);
      break;
    case WRITE:
      t = jj_consume_token(WRITE);
      break;
    default:
      jj_la1[42] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
        {if (true) return t.image;}
    throw new Error("Missing return statement in function");
  }

  final private boolean jj_2_1(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_1(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(0, xla); }
  }

  final private boolean jj_2_2(int xla) {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_2(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(1, xla); }
  }

  final private boolean jj_3_1() {
    if (jj_3R_20()) return true;
    return false;
  }

  final private boolean jj_3R_22() {
    if (jj_scan_token(STRING_LITERAL)) return true;
    return false;
  }

  final private boolean jj_3R_21() {
    if (jj_scan_token(EXTENSION)) return true;
    if (jj_scan_token(LPAREN)) return true;
    if (jj_scan_token(INCLUDE)) return true;
    return false;
  }

  final private boolean jj_3R_20() {
    if (jj_scan_token(EXTENSION)) return true;
    if (jj_3R_22()) return true;
    if (jj_scan_token(EXTENSION)) return true;
    return false;
  }

  final private boolean jj_3_2() {
    if (jj_3R_21()) return true;
    return false;
  }

  public ParserTokenManager token_source;
  SimpleCharStream jj_input_stream;
  public Token token, jj_nt;
  private Token jj_scanpos, jj_lastpos;
  private int jj_la;
  public boolean lookingAhead = false;
  private boolean jj_semLA;
  private int jj_gen;
  final private int[] jj_la1 = new int[43];
  static private int[] jj_la1_0;
  static private int[] jj_la1_1;
  static private int[] jj_la1_2;
  static {
      jj_la1_0();
      jj_la1_1();
      jj_la1_2();
   }
   private static void jj_la1_0() {
      jj_la1_0 = new int[] {0x0,0x3a80000,0x540000,0xffff0000,0x0,0xffff0000,0x0,0xffff0000,0x0,0x800,0xffff0000,0x10000,0xffff0000,0xffff0000,0x23a80000,0x200,0xffff0000,0xffff0000,0xffff0000,0x6bfe0000,0x8000,0x0,0xffff0000,0x800,0xffff0400,0x8000,0x800,0x8000,0x800,0x0,0x0,0x0,0x8800,0x0,0xffff0000,0xffff0000,0xffff0000,0x80000000,0x0,0xffff0000,0x4000000,0x0,0xffff0000,};
   }
   private static void jj_la1_1() {
      jj_la1_1 = new int[] {0x18000100,0x0,0x0,0xffffffff,0x0,0xffffffff,0x0,0xffffffff,0x0,0x0,0xffffffff,0x1,0xffffffff,0xffffffff,0x1000000,0x14000000,0xffffffff,0xffffffff,0xffffffff,0x1580806,0x0,0x0,0xffffffff,0x0,0xffffffff,0x0,0x0,0x0,0x0,0x2010000,0x2010000,0x8080,0x0,0x40004000,0xffffffff,0xffffffff,0xffffffff,0x10,0x80002000,0xffffffff,0x620,0xa00000,0xffffffff,};
   }
   private static void jj_la1_2() {
      jj_la1_2 = new int[] {0x0,0x0,0x0,0x4fff,0x2000,0x4fff,0x2000,0x4fff,0x2000,0x0,0x4fff,0x0,0x7fff,0x7fff,0x40,0x800,0x7fff,0x7fff,0x7fff,0x3d6,0x0,0x2000,0x4fff,0x0,0x4fff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x4fff,0x7fff,0x7fff,0x0,0x0,0x4fff,0x28,0x0,0xfff,};
   }
  final private JJCalls[] jj_2_rtns = new JJCalls[2];
  private boolean jj_rescan = false;
  private int jj_gc = 0;

  public Parser(java.io.InputStream stream) {
    jj_input_stream = new SimpleCharStream(stream, 1, 1);
    token_source = new ParserTokenManager(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 43; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  public void ReInit(java.io.InputStream stream) {
    jj_input_stream.ReInit(stream, 1, 1);
    token_source.ReInit(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 43; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  public Parser(java.io.Reader stream) {
    jj_input_stream = new SimpleCharStream(stream, 1, 1);
    token_source = new ParserTokenManager(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 43; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  public void ReInit(java.io.Reader stream) {
    jj_input_stream.ReInit(stream, 1, 1);
    token_source.ReInit(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 43; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  public Parser(ParserTokenManager tm) {
    token_source = tm;
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 43; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  public void ReInit(ParserTokenManager tm) {
    token_source = tm;
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 43; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  final private Token jj_consume_token(int kind) throws ParseException {
    Token oldToken = token;
    if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
    else jj_nt = jj_nt.next = token_source.getNextToken();
    if (token.kind == kind) {
      jj_gen++;
      if (++jj_gc > 100) {
        jj_gc = 0;
        for (int i = 0; i < jj_2_rtns.length; i++) {
          JJCalls c = jj_2_rtns[i];
          while (c != null) {
            if (c.gen < jj_gen) c.first = null;
            c = c.next;
          }
        }
      }
      return token;
    }
    jj_nt = token;
    token = oldToken;
    jj_kind = kind;
    throw generateParseException();
  }

  static private final class LookaheadSuccess extends java.lang.Error { }
  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
  final private boolean jj_scan_token(int kind) {
    if (jj_scanpos == jj_lastpos) {
      jj_la--;
      if (jj_scanpos.next == null) {
        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
      } else {
        jj_lastpos = jj_scanpos = jj_scanpos.next;
      }
    } else {
      jj_scanpos = jj_scanpos.next;
    }
    if (jj_rescan) {
      int i = 0; Token tok = token;
      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
      if (tok != null) jj_add_error_token(kind, i);
    }
    if (jj_scanpos.kind != kind) return true;
    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
    return false;
  }

  final public Token getNextToken() {
    if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
    else jj_nt = jj_nt.next = token_source.getNextToken();
    jj_gen++;
    return token;
  }

  final public Token getToken(int index) {
    Token t = lookingAhead ? jj_scanpos : token;
    for (int i = 0; i < index; i++) {
      if (t.next != null) t = t.next;
      else t = t.next = token_source.getNextToken();
    }
    return t;
  }

  private java.util.Vector jj_expentries = new java.util.Vector();
  private int[] jj_expentry;
  private int jj_kind = -1;
  private int[] jj_lasttokens = new int[100];
  private int jj_endpos;

  private void jj_add_error_token(int kind, int pos) {
    if (pos >= 100) return;
    if (pos == jj_endpos + 1) {
      jj_lasttokens[jj_endpos++] = kind;
    } else if (jj_endpos != 0) {
      jj_expentry = new int[jj_endpos];
      for (int i = 0; i < jj_endpos; i++) {
        jj_expentry[i] = jj_lasttokens[i];
      }
      boolean exists = false;
      for (java.util.Enumeration e = jj_expentries.elements(); e.hasMoreElements();) {
        int[] oldentry = (int[])(e.nextElement());
        if (oldentry.length == jj_expentry.length) {
          exists = true;
          for (int i = 0; i < jj_expentry.length; i++) {
            if (oldentry[i] != jj_expentry[i]) {
              exists = false;
              break;
            }
          }
          if (exists) break;
        }
      }
      if (!exists) jj_expentries.addElement(jj_expentry);
      if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
    }
  }

  public ParseException generateParseException() {
    jj_expentries.removeAllElements();
    boolean[] la1tokens = new boolean[81];
    for (int i = 0; i < 81; i++) {
      la1tokens[i] = false;
    }
    if (jj_kind >= 0) {
      la1tokens[jj_kind] = true;
      jj_kind = -1;
    }
    for (int i = 0; i < 43; i++) {
      if (jj_la1[i] == jj_gen) {
        for (int j = 0; j < 32; j++) {
          if ((jj_la1_0[i] & (1<<j)) != 0) {
            la1tokens[j] = true;
          }
          if ((jj_la1_1[i] & (1<<j)) != 0) {
            la1tokens[32+j] = true;
          }
          if ((jj_la1_2[i] & (1<<j)) != 0) {
            la1tokens[64+j] = true;
          }
        }
      }
    }
    for (int i = 0; i < 81; i++) {
      if (la1tokens[i]) {
        jj_expentry = new int[1];
        jj_expentry[0] = i;
        jj_expentries.addElement(jj_expentry);
      }
    }
    jj_endpos = 0;
    jj_rescan_token();
    jj_add_error_token(0, 0);
    int[][] exptokseq = new int[jj_expentries.size()][];
    for (int i = 0; i < jj_expentries.size(); i++) {
      exptokseq[i] = (int[])jj_expentries.elementAt(i);
    }
    return new ParseException(token, exptokseq, tokenImage);
  }

  final public void enable_tracing() {
  }

  final public void disable_tracing() {
  }

  final private void jj_rescan_token() {
    jj_rescan = true;
    for (int i = 0; i < 2; i++) {
      JJCalls p = jj_2_rtns[i];
      do {
        if (p.gen > jj_gen) {
          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
          switch (i) {
            case 0: jj_3_1(); break;
            case 1: jj_3_2(); break;
          }
        }
        p = p.next;
      } while (p != null);
    }
    jj_rescan = false;
  }

  final private void jj_save(int index, int xla) {
    JJCalls p = jj_2_rtns[index];
    while (p.gen > jj_gen) {
      if (p.next == null) { p = p.next = new JJCalls(); break; }
      p = p.next;
    }
    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
  }

  static final class JJCalls {
    int gen;
    Token first;
    int arg;
    JJCalls next;
  }

}
