/**
   * Assigns the mapped colors to the FSTDirectives from the changed document.
   *
   * @return the directive list
   */
  private void updateDirectives() {
    ListIterator<FSTDirective> newDirIt = getNewDirectives().listIterator(0);

    while (newDirIt.hasNext()) {
      FSTDirective newDir = newDirIt.next();
      FSTDirective oldDir = directiveMap.get(newDir.getId());

      if (oldDir != null
          && newDir.getCommand() == oldDir.getCommand()
          && newDir.getFeatureNames().equals(oldDir.getFeatureNames())) {

        oldDir.setStartLine(newDir.getStartLine(), newDir.getStartOffset());
        oldDir.setEndLine(newDir.getEndLine(), newDir.getEndLength());
      } else {
        directiveMap.clear();
        return;
      }

      if (newDir.hasChildren()) {
        for (FSTDirective newDirChild : newDir.getChildrenList()) {
          newDirIt.add(newDirChild);
          newDirIt.previous();
        }
      }
    }
  }
  @Override
  public LinkedList<FSTDirective> buildModelDirectivesForFile(Vector<String> lines) {
    // for preprocessor outline
    Stack<FSTDirective> directivesStack = new Stack<FSTDirective>();
    LinkedList<FSTDirective> directivesList = new LinkedList<FSTDirective>();
    int id = 0;

    for (int i = 0; i < lines.size(); i++) {
      String line = lines.get(i);

      // if line is preprocessor directive
      if (containsRegex(line, "//\\s*#")) {
        FSTDirectiveCommand command = null;

        if (containsRegex(line, "//\\s*#if[ (]")) { // 1
          command = FSTDirectiveCommand.IF;
        } else if (containsRegex(line, "//\\s*#ifdef[ (]")) { // 2
          command = FSTDirectiveCommand.IFDEF;
        } else if (containsRegex(line, "//\\s*#ifndef[ (]")) { // 3
          command = FSTDirectiveCommand.IFNDEF;
        } else if (containsRegex(line, "//\\s*#elif[ (]")) { // 4
          command = FSTDirectiveCommand.ELIF;
        } else if (containsRegex(line, "//\\s*#elifdef[ (]")) { // 5
          command = FSTDirectiveCommand.ELIFDEF;
        } else if (containsRegex(line, "//\\s*#elifndef[ (]")) { // 6
          command = FSTDirectiveCommand.ELIFNDEF;
        } else if (containsRegex(line, "//\\s*#else")) { // 7
          command = FSTDirectiveCommand.ELSE;
        } else if (containsRegex(line, "//\\s*#condition[ (]")) { // 8
          command = FSTDirectiveCommand.CONDITION;
        } else if (containsRegex(line, "//\\s*#define[ (]")) { // 9
          command = FSTDirectiveCommand.DEFINE;
        } else if (containsRegex(line, "//\\s*#undefine[ (]")) { // 10
          command = FSTDirectiveCommand.UNDEFINE;
        } else if (!containsRegex(line, "//\\s*#endif")) { // 11
          continue;
        }

        if (command == null) {
          if (!directivesStack.isEmpty()) {
            directivesStack.peek().setEndLine(i, line.length());
            while (!directivesStack.isEmpty()) {
              FSTDirective parent = directivesStack.pop();
              if (parent.getCommand() != FSTDirectiveCommand.ELIF
                  && parent.getCommand() != FSTDirectiveCommand.ELIFDEF
                  && parent.getCommand() != FSTDirectiveCommand.ELIFNDEF
                  && parent.getCommand() != FSTDirectiveCommand.ELSE) {
                break;
              }
            }
          }
        } else {
          FSTDirective directive = new FSTDirective();

          if (command == FSTDirectiveCommand.ELSE) {
            if (!directivesStack.isEmpty()) {
              directivesStack.peek().setEndLine(i, 0);
              directive.setFeatureNames(directivesStack.peek().getFeatureNames());
            }
          } else if (command == FSTDirectiveCommand.ELIF
              || command == FSTDirectiveCommand.ELIFDEF
              || command == FSTDirectiveCommand.ELIFNDEF) {
            if (!directivesStack.isEmpty()) {
              directivesStack.peek().setEndLine(i, 0);
            }
          }

          directive.setCommand(command);

          Matcher m = patternCommands.matcher(line);
          line = m.replaceAll("").trim();

          if (directive.getFeatureNames() == null) {
            directive.setFeatureNames(getFeatureNames(line));
          }
          directive.setExpression(line);
          directive.setStartLine(i, 0);
          directive.setId(id++);

          if (directivesStack.isEmpty()) {
            directivesList.add(directive);
          } else {
            directivesStack.peek().addChild(directive);
          }

          if (command != FSTDirectiveCommand.DEFINE
              && command != FSTDirectiveCommand.UNDEFINE
              && command != FSTDirectiveCommand.CONDITION) directivesStack.push(directive);
        }
      }
    }
    return directivesList;
  }