/**
   * This method performs the morphology for pronouns.
   *
   * @param element the <code>InflectedWordElement</code>.
   * @return a <code>StringElement</code> representing the word after inflection.
   */
  public NLGElement doPronounMorphology(InflectedWordElement element) {
    String realised = null;

    if (!element.getFeatureAsBoolean(InternalFeature.NON_MORPH).booleanValue()) {
      Object genderValue = element.getFeature(LexicalFeature.GENDER);
      Object personValue = element.getFeature(Feature.PERSON);

      // way of getting discourseValue changed by vaudrypl
      NLGElement parent = element.getParent();
      Object discourseValue = element.getFeature(InternalFeature.DISCOURSE_FUNCTION);
      if (discourseValue == DiscourseFunction.SUBJECT
          && parent != null
          && parent.isA(PhraseCategory.NOUN_PHRASE)) {
        discourseValue = parent.getFeature(InternalFeature.DISCOURSE_FUNCTION);
      }
      if (!(discourseValue instanceof DiscourseFunction))
        discourseValue = DiscourseFunction.SUBJECT;

      int numberIndex = element.isPlural() ? 1 : 0;
      int genderIndex = (genderValue instanceof Gender) ? ((Gender) genderValue).ordinal() : 2;

      int personIndex = (personValue instanceof Person) ? ((Person) personValue).ordinal() : 2;

      if (personIndex == 2) {
        personIndex += genderIndex;
      }

      int positionIndex = 0;

      if (element.getFeatureAsBoolean(LexicalFeature.REFLEXIVE).booleanValue()) {
        positionIndex = 2;
      } else if (element.getFeatureAsBoolean(Feature.POSSESSIVE).booleanValue()) {
        positionIndex = 3;
        if (DiscourseFunction.SPECIFIER.equals(discourseValue)) {
          positionIndex++;
        }
      } else {
        positionIndex =
            (DiscourseFunction.SUBJECT.equals(discourseValue)
                        && !element.getFeatureAsBoolean(Feature.PASSIVE).booleanValue())
                    || (DiscourseFunction.OBJECT.equals(discourseValue)
                        && element.getFeatureAsBoolean(Feature.PASSIVE).booleanValue())
                    || DiscourseFunction.SPECIFIER.equals(discourseValue)
                    || (DiscourseFunction.COMPLEMENT.equals(discourseValue)
                        && element.getFeatureAsBoolean(Feature.PASSIVE).booleanValue())
                ? 0
                : 1;
      }
      realised = PRONOUNS[numberIndex][positionIndex][personIndex];
    } else {
      realised = element.getBaseForm();
    }
    // vaudrypl added element as 2nd argument
    StringElement realisedElement = new StringElement(realised, element);
    realisedElement.setFeature(
        InternalFeature.DISCOURSE_FUNCTION, element.getFeature(InternalFeature.DISCOURSE_FUNCTION));

    return realisedElement;
  }
  /**
   * Determines the maximim position at which this modifier can occur.
   *
   * @param modifier the modifier to be checked.
   * @return the maximum position for this modifier.
   */
  private static int getMaxPos(NLGElement modifier) {
    int position = NOUN_POSITION;

    if (modifier.isA(LexicalCategory.ADJECTIVE) || modifier.isA(PhraseCategory.ADJECTIVE_PHRASE)) {
      WordElement adjective = getHeadWordElement(modifier);

      if (adjective.getFeatureAsBoolean(LexicalFeature.CLASSIFYING).booleanValue()) {
        position = CLASSIFYING_POSITION;
      } else if (adjective.getFeatureAsBoolean(LexicalFeature.COLOUR).booleanValue()) {
        position = COLOUR_POSITION;
      } else if (adjective.getFeatureAsBoolean(LexicalFeature.QUALITATIVE).booleanValue()) {
        position = QUALITATIVE_POSITION;
      } else {
        position = CLASSIFYING_POSITION;
      }
    }
    return position;
  }
  /**
   * Realises the specifier of the noun phrase.
   *
   * @param phrase the <code>PhraseElement</code> representing this noun phrase.
   * @param parent the parent <code>SyntaxProcessor</code> that will do the realisation of the
   *     complementiser.
   * @param realisedElement the current realisation of the noun phrase.
   */
  private static void realiseSpecifier(
      PhraseElement phrase, SyntaxProcessor parent, ListElement realisedElement) {
    NLGElement specifierElement = phrase.getFeatureAsElement(InternalFeature.SPECIFIER);

    if (specifierElement != null
        && !phrase.getFeatureAsBoolean(InternalFeature.RAISED).booleanValue()
        && !phrase.getFeatureAsBoolean(Feature.ELIDED).booleanValue()) {

      if (!specifierElement.isA(LexicalCategory.PRONOUN)) {
        specifierElement.setFeature(Feature.NUMBER, phrase.getFeature(Feature.NUMBER));
      }

      NLGElement currentElement = parent.realise(specifierElement);

      if (currentElement != null) {
        currentElement.setFeature(InternalFeature.DISCOURSE_FUNCTION, DiscourseFunction.SPECIFIER);
        realisedElement.addComponent(currentElement);
      }
    }
  }