private void _addSassString(SassFile sassFile, String fileName, String sassContent)
      throws Exception {

    sassContent = sassContent.trim();

    if (sassContent.isEmpty()) {
      return;
    }

    String cssContent = _parseSass(fileName, CSSBuilderUtil.parseStaticTokens(sassContent));

    sassFile.addSassFragment(new SassString(this, fileName, cssContent));
  }
  private boolean _isModified(String dirName, String[] fileNames) throws Exception {

    for (String fileName : fileNames) {
      if (fileName.contains("_rtl")) {
        continue;
      }

      fileName = _normalizeFileName(dirName, fileName);

      File file = new File(fileName);
      File cacheFile = CSSBuilderUtil.getCacheFile(fileName);

      if (file.lastModified() != cacheFile.lastModified()) {
        return true;
      }
    }

    return false;
  }
  private void _parseSassFile(SassFile sassFile) throws Exception {
    String fileName = sassFile.getFileName();

    long start = System.currentTimeMillis();

    File file = new File(_docrootDirName, fileName);

    if (!file.exists()) {
      return;
    }

    String content = _read(file);

    int pos = 0;

    StringBundler sb = new StringBundler();

    while (true) {
      int commentX = content.indexOf(_CSS_COMMENT_BEGIN, pos);
      int commentY = content.indexOf(_CSS_COMMENT_END, commentX + _CSS_COMMENT_BEGIN.length());

      int importX = content.indexOf(_CSS_IMPORT_BEGIN, pos);
      int importY = content.indexOf(_CSS_IMPORT_END, importX + _CSS_IMPORT_BEGIN.length());

      if ((importX == -1) || (importY == -1)) {
        sb.append(content.substring(pos));

        break;
      } else if ((commentX != -1)
          && (commentY != -1)
          && (commentX < importX)
          && (commentY > importX)) {

        commentY += _CSS_COMMENT_END.length();

        sb.append(content.substring(pos, commentY));

        pos = commentY;
      } else {
        sb.append(content.substring(pos, importX));

        String mediaQuery = StringPool.BLANK;

        int mediaQueryImportX =
            content.indexOf(CharPool.CLOSE_PARENTHESIS, importX + _CSS_IMPORT_BEGIN.length());
        int mediaQueryImportY =
            content.indexOf(CharPool.SEMICOLON, importX + _CSS_IMPORT_BEGIN.length());

        String importFileName = null;

        if (importY != mediaQueryImportX) {
          mediaQuery = content.substring(mediaQueryImportX + 1, mediaQueryImportY);

          importFileName =
              content.substring(importX + _CSS_IMPORT_BEGIN.length(), mediaQueryImportX);
        } else {
          importFileName = content.substring(importX + _CSS_IMPORT_BEGIN.length(), importY);
        }

        if (!importFileName.isEmpty()) {
          if (importFileName.charAt(0) != CharPool.SLASH) {
            importFileName = _fixRelativePath(sassFile.getBaseDir().concat(importFileName));
          }

          SassFile importSassFile = _build(importFileName);

          if (Validator.isNotNull(mediaQuery)) {
            sassFile.addSassFragment(new SassFileWithMediaQuery(importSassFile, mediaQuery));
          } else {
            sassFile.addSassFragment(importSassFile);
          }
        }

        // LEP-7540

        if (Validator.isNotNull(mediaQuery)) {
          pos = mediaQueryImportY + 1;
        } else {
          pos = importY + _CSS_IMPORT_END.length();
        }
      }
    }

    _addSassString(sassFile, fileName, sb.toString());

    String rtlCustomFileName = CSSBuilderUtil.getRtlCustomFileName(fileName);

    File rtlCustomFile = new File(_docrootDirName, rtlCustomFileName);

    if (rtlCustomFile.exists()) {
      _addSassString(sassFile, rtlCustomFileName, _read(rtlCustomFile));
    }

    sassFile.setElapsedTime(System.currentTimeMillis() - start);
  }