/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <iostream>
#include <sstream>

#include "Generator.h"
#include "Specification.h"
#include "Utilities.h"

using namespace std;

struct DetailedFunctionEntry {
    VersionInfo info;
    string htmlDeclaration;
};

static const char OVERVIEW_HTML_FILE_NAME[] = "overview.html";
static const char OVERVIEW_JD_FILE_NAME[] = "overview.jd";
static const char INDEX_HTML_FILE_NAME[] = "index.html";
static const char INDEX_JD_FILE_NAME[] = "index.jd";

static void writeHeader(GeneratedFile* file, bool forVerification, const string& title) {
    if (forVerification) {
        *file << "<!DOCTYPE html>\n";
        *file << "<!-- " << AUTO_GENERATED_WARNING << "-->\n";
        *file << "<html><head>\n"
                 "<title>RenderScript Reference</title>\n"
                 "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>\n"
                 "<link rel='stylesheet' "
                 "href='http://fonts.googleapis.com/css?family=Roboto+Condensed'>\n"
                 "<link rel='stylesheet' href='http://fonts.googleapis.com/"
                 "css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold' "
                 "title='roboto'>\n"
                 "<link href='default.css' rel='stylesheet' type='text/css'>\n"
                 "<link href='fullscreen.css' rel='stylesheet' class='fullscreen' "
                 "type='text/css'>\n"
                 "<body class='gc-documentation develop reference'>\n\n";
        *file << "<h1>" << title << "</h1>\n";
    } else {
        *file << "page.title=RenderScript " << title << "\n\n";
        *file << "@jd:body\n\n";
    }
    *file << "<div class='renderscript'>\n";
}

static void writeFooter(GeneratedFile* file, bool forVerification) {
    *file << "</div>\n";
    if (forVerification) {
        *file << "</body></html>\n";
    }
}

// If prefix starts input, copy it to stream and remove it from input.
static void skipPrefix(ostringstream* stream, string* input, const string& prefix) {
    size_t size = prefix.size();
    if (input->compare(0, size, prefix) != 0) {
        return;
    }
    input->erase(0, size);
    *stream << prefix;
}

// Merge b into a.  Returns true if successful
static bool mergeVersionInfo(VersionInfo* a, const VersionInfo& b) {
    if (a->intSize != b.intSize) {
        cerr << "Error.  We don't currently support versions that differ based on int size\n";
        return false;
    }
    if (b.minVersion != 0 && a->maxVersion == b.minVersion - 1) {
        a->maxVersion = b.maxVersion;
    } else if (b.maxVersion != 0 && a->minVersion == b.maxVersion + 1) {
        a->minVersion = b.minVersion;
    } else {
        cerr << "Error.  This code currently assume that all versions are contiguous.  Don't know "
                "how to merge versions (" << a->minVersion << " - " << a->maxVersion << ") and ("
             << b.minVersion << " - " << b.maxVersion << ")\n";
        return false;
    }
    return true;
}

static string getHtmlStringForType(const ParameterDefinition& parameter) {
    string s = parameter.rsType;
    ostringstream stream;
    skipPrefix(&stream, &s, "const ");
    skipPrefix(&stream, &s, "volatile ");
    bool endsWithAsterisk = s.size() > 0 && s[s.size() - 1] == '*';
    if (endsWithAsterisk) {
        s.erase(s.size() - 1, 1);
    }

    string anchor = systemSpecification.getHtmlAnchor(s);
    if (anchor.empty()) {
        // Not a RenderScript specific type.
        return parameter.rsType;
    } else {
        stream << anchor;
    }
    if (endsWithAsterisk) {
        stream << "*";
    }
    return stream.str();
}

static string getDetailedHtmlDeclaration(const FunctionPermutation& permutation) {
    ostringstream stream;
    auto ret = permutation.getReturn();
    if (ret) {
        stream << getHtmlStringForType(*ret);
    } else {
        stream << "void";
    }
    stream << " " << permutation.getName() << "(";
    bool needComma = false;
    for (auto p : permutation.getParams()) {
        if (needComma) {
            stream << ", ";
        }
        stream << getHtmlStringForType(*p);
        if (p->isOutParameter) {
            stream << "*";
        }
        if (!p->specName.empty()) {
            stream << " " << p->specName;
        }
        needComma = true;
    }
    stream << ");\n";
    return stream.str();
}

/* Some functions (like max) have changed implementations but not their
 * declaration.  We need to unify these so that we don't end up with entries
 * like:
 *   char max(char a, char b);  Removed from API level 20
 *   char max(char a, char b);  Added to API level 20
 */
static bool getUnifiedFunctionPrototypes(Function* function,
                                         map<string, DetailedFunctionEntry>* entries) {
    for (auto f : function->getSpecifications()) {
        DetailedFunctionEntry entry;
        entry.info = f->getVersionInfo();
        for (auto p : f->getPermutations()) {
            entry.htmlDeclaration = getDetailedHtmlDeclaration(*p);
            const string s = stripHtml(entry.htmlDeclaration);
            auto i = entries->find(s);
            if (i == entries->end()) {
                entries->insert(pair<string, DetailedFunctionEntry>(s, entry));
            } else {
                if (!mergeVersionInfo(&i->second.info, entry.info)) {
                    return false;
                }
            }
        }
    }
    return true;
}

// Convert words starting with @ into HTML references.  Returns false if error.
static bool convertDocumentationRefences(string* s) {
    bool success = true;
    size_t end = 0;
    for (;;) {
        size_t start = s->find('@', end);
        if (start == string::npos) {
            break;
        }
        // Find the end of the identifier
        end = start;
        char c;
        do {
            c = (*s)[++end];
        } while (isalnum(c) || c == '_');

        const string id = s->substr(start + 1, end - start - 1);
        string anchor = systemSpecification.getHtmlAnchor(id);
        if (anchor.empty()) {
            cerr << "Error:  Can't convert the documentation reference @" << id << "\n";
            success = false;
        }
        s->replace(start, end - start, anchor);
    }
    return success;
}

static bool generateHtmlParagraphs(GeneratedFile* file, const vector<string>& description) {
    bool inParagraph = false;
    for (auto s : description) {
        // Empty lines in the .spec marks paragraphs.
        if (s.empty()) {
            if (inParagraph) {
                *file << "</p>\n";
                inParagraph = false;
            }
        } else {
            if (!inParagraph) {
                *file << "<p> ";
                inParagraph = true;
            }
        }
        if (!convertDocumentationRefences(&s)) {
            return false;
        }
        *file << s << "\n";
    }
    if (inParagraph) {
        *file << "</p>\n";
    }
    return true;
}

static void writeSummaryTableStart(GeneratedFile* file, const string& label, bool labelIsHeading) {
    if (labelIsHeading) {
        *file << "<h2 style='margin-bottom: 0px;'>" << label << "</h2>\n";
    }
    *file << "<table class='jd-sumtable'><tbody>\n";
    if (!labelIsHeading) {
        *file << "  <tr><th colspan='2'>" << label << "</th></tr>\n";
    }
}

static void writeSummaryTableEnd(GeneratedFile* file) {
    *file << "</tbody></table>\n";
}

enum DeprecatedSelector {
    DEPRECATED_ONLY,
    NON_DEPRECATED_ONLY,
    ALL,
};

static void writeSummaryTableEntry(ostream* stream, Definition* definition,
                                   DeprecatedSelector deprecatedSelector) {
    if (definition->hidden()) {
        return;
    }
    const bool deprecated = definition->deprecated();
    if ((deprecatedSelector == DEPRECATED_ONLY && !deprecated) ||
        (deprecatedSelector == NON_DEPRECATED_ONLY && deprecated)) {
        return;
    }

    *stream << "  <tr class='alt-color api apilevel-1'>\n";
    *stream << "    <td class='jd-linkcol'>\n";
    *stream << "      <a href='" << definition->getUrl() << "'>" << definition->getName()
            << "</a>\n";
    *stream << "    </td>\n";
    *stream << "    <td class='jd-descrcol' width='100%'>\n";
    *stream << "      ";
    if (deprecated) {
        *stream << "<b>Deprecated</b>.  ";
    }
    *stream << definition->getSummary() << "\n";
    *stream << "    </td>\n";
    *stream << "  </tr>\n";
}

static void writeSummaryTable(GeneratedFile* file, const ostringstream* entries, const char* name,
                              DeprecatedSelector deprecatedSelector, bool labelAsHeader) {
    string s = entries->str();
    if (!s.empty()) {
        string prefix;
        if (deprecatedSelector == DEPRECATED_ONLY) {
            prefix = "Deprecated ";
        }
        writeSummaryTableStart(file, prefix + name, labelAsHeader);
        *file << s;
        writeSummaryTableEnd(file);
    }
}

static void writeSummaryTables(GeneratedFile* file, const map<string, Constant*>& constants,
                               const map<string, Type*>& types,
                               const map<string, Function*>& functions,
                               DeprecatedSelector deprecatedSelector, bool labelAsHeader) {
    ostringstream constantStream;
    for (auto e : constants) {
        writeSummaryTableEntry(&constantStream, e.second, deprecatedSelector);
    }
    writeSummaryTable(file, &constantStream, "Constants", deprecatedSelector, labelAsHeader);

    ostringstream typeStream;
    for (auto e : types) {
        writeSummaryTableEntry(&typeStream, e.second, deprecatedSelector);
    }
    writeSummaryTable(file, &typeStream, "Types", deprecatedSelector, labelAsHeader);

    ostringstream functionStream;
    for (auto e : functions) {
        writeSummaryTableEntry(&functionStream, e.second, deprecatedSelector);
    }
    writeSummaryTable(file, &functionStream, "Functions", deprecatedSelector, labelAsHeader);
}

static void writeHtmlVersionTag(GeneratedFile* file, VersionInfo info,
                                bool addSpacing) {
    ostringstream stream;
    if (info.intSize == 32) {
        stream << "When compiling for 32 bits. ";
    } else if (info.intSize == 64) {
        stream << "When compiling for 64 bits. ";
    }

    if (info.minVersion > 1 || info.maxVersion) {
        const char* mid =
                    "<a "
                    "href='http://developer.android.com/guide/topics/manifest/"
                    "uses-sdk-element.html#ApiLevels'>API level ";
        if (info.minVersion <= 1) {
            // No minimum
            if (info.maxVersion > 0) {
                stream << "Removed from " << mid << info.maxVersion + 1 << " and higher";
            }
        } else {
            if (info.maxVersion == 0) {
                // No maximum
                stream << "Added in " << mid << info.minVersion;
            } else {
                stream << mid << info.minVersion << " - " << info.maxVersion;
            }
        }
        stream << "</a>";
    }
    string s = stream.str();
    // Remove any trailing whitespace
    while (s.back() == ' ') {
        s.pop_back();
    }
    if (!s.empty()) {
        *file << (addSpacing ? "    " : "") << s << "\n";
    }
}

static void writeDetailedTypeSpecification(GeneratedFile* file, const TypeSpecification* spec) {
    switch (spec->getKind()) {
        case SIMPLE: {
            Type* type = spec->getType();
            *file << "<p>A typedef of: " << spec->getSimpleType()
                  << makeAttributeTag(spec->getAttribute(), "", type->getDeprecatedApiLevel(),
                                      type->getDeprecatedMessage())
                  << "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
            writeHtmlVersionTag(file, spec->getVersionInfo(), false);
            *file << "</p>\n";
            break;
        }
        case RS_OBJECT: {
            *file << "<p>";
            writeHtmlVersionTag(file, spec->getVersionInfo(), false);
            *file << "</p>\n";
            break;
        }
        case ENUM: {
            *file << "<p>An enum with the following values:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n";
            writeHtmlVersionTag(file, spec->getVersionInfo(), false);
            *file << "</p>\n";

            *file << "  <table class='jd-tagtable'><tbody>\n";
            const vector<string>& values = spec->getValues();
            const vector<string>& valueComments = spec->getValueComments();
            for (size_t i = 0; i < values.size(); i++) {
                *file << "    <tr><th>" << values[i] << "</th><td>";
                if (valueComments.size() > i) {
                    *file << valueComments[i];
                }
                *file << "</td></tr>\n";
            }
            *file << "  </tbody></table><br/>\n";
            break;
        }
        case STRUCT: {
            *file << "<p>A structure with the following fields:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
            writeHtmlVersionTag(file, spec->getVersionInfo(), false);
            *file << "</p>\n";

            *file << "  <table class='jd-tagtable'><tbody>\n";
            const vector<string>& fields = spec->getFields();
            const vector<string>& fieldComments = spec->getFieldComments();
            for (size_t i = 0; i < fields.size(); i++) {
                *file << "    <tr><th>" << fields[i] << "</th><td>";
                if (fieldComments.size() > i && !fieldComments[i].empty()) {
                    *file << fieldComments[i];
                }
                *file << "</td></tr>\n";
            }
            *file << "  </tbody></table><br/>\n";
            break;
        }
    }
}

static void writeDetailedConstantSpecification(GeneratedFile* file, ConstantSpecification* c) {
    *file << "      <tr><td>";
    *file << "Value: " << c->getValue() << "\n";
    writeHtmlVersionTag(file, c->getVersionInfo(), true);
    *file << "      </td></tr>\n";
    *file << "<br/>\n";
}

static bool writeOverviewForFile(GeneratedFile* file, const SpecFile& specFile) {
    bool success = true;
    *file << "<h2>" << specFile.getBriefDescription() << "</h2>\n";
    if (!generateHtmlParagraphs(file, specFile.getFullDescription())) {
        success = false;
    }

    // Write the summary tables.
    // file << "<h2>Summary</h2>\n";
    writeSummaryTables(file, specFile.getDocumentedConstants(), specFile.getDocumentedTypes(),
                       specFile.getDocumentedFunctions(), NON_DEPRECATED_ONLY, false);

    return success;
}

static bool generateOverview(const string& directory, bool forVerification) {
    GeneratedFile file;
    if (!file.start(directory, forVerification ? OVERVIEW_HTML_FILE_NAME : OVERVIEW_JD_FILE_NAME)) {
        return false;
    }
    bool success = true;

    writeHeader(&file, forVerification, "Runtime API Reference");

    for (auto specFile : systemSpecification.getSpecFiles()) {
        if (!writeOverviewForFile(&file, *specFile)) {
            success = false;
        }
    }

    writeFooter(&file, forVerification);
    file.close();
    return success;
}

static bool generateAlphabeticalIndex(const string& directory, bool forVerification) {
    GeneratedFile file;
    if (!file.start(directory, forVerification ? INDEX_HTML_FILE_NAME : INDEX_JD_FILE_NAME)) {
        return false;
    }
    writeHeader(&file, forVerification, "Index");

    writeSummaryTables(&file, systemSpecification.getConstants(), systemSpecification.getTypes(),
                       systemSpecification.getFunctions(), NON_DEPRECATED_ONLY, true);

    writeSummaryTables(&file, systemSpecification.getConstants(), systemSpecification.getTypes(),
                       systemSpecification.getFunctions(), DEPRECATED_ONLY, true);

    writeFooter(&file, forVerification);
    file.close();
    return true;
}

static void writeDeprecatedWarning(GeneratedFile* file, Definition* definition) {
    if (definition->deprecated()) {
        *file << "    <p><b>Deprecated.</b>  ";
        string s = definition->getDeprecatedMessage();
        convertDocumentationRefences(&s);
        if (!s.empty()) {
            *file << s;
        } else {
            *file << "Do not use.";
        }
        *file << "</p>\n";
    }
}

static bool writeDetailedConstant(GeneratedFile* file, Constant* constant) {
    if (constant->hidden()) {
        return true;
    }
    const string& name = constant->getName();

    *file << "<a name='android_rs:" << name << "'></a>\n";
    *file << "<div class='jd-details'>\n";
    *file << "  <h4 class='jd-details-title'>\n";
    *file << "    <span class='sympad'>" << name << "</span>\n";
    *file << "    <span class='normal'>: " << constant->getSummary() << "</span>\n";
    *file << "  </h4>\n";

    *file << "  <div class='jd-details-descr'>\n";
    *file << "    <table class='jd-tagtable'><tbody>\n";
    auto specifications = constant->getSpecifications();
    bool addSeparator = specifications.size() > 1;
    for (auto spec : specifications) {
        if (addSeparator) {
            *file << "    <h5 class='jd-tagtitle'>Variant:</h5>\n";
        }
        writeDetailedConstantSpecification(file, spec);
    }
    *file << "    </tbody></table>\n";
    *file << "  </div>\n";

    *file << "    <div class='jd-tagdata jd-tagdescr'>\n";

    writeDeprecatedWarning(file, constant);
    if (!generateHtmlParagraphs(file, constant->getDescription())) {
        return false;
    }
    *file << "    </div>\n";

    *file << "</div>\n";
    *file << "\n";
    return true;
}

static bool writeDetailedType(GeneratedFile* file, Type* type) {
    if (type->hidden()) {
        return true;
    }
    const string& name = type->getName();

    *file << "<a name='android_rs:" << name << "'></a>\n";
    *file << "<div class='jd-details'>\n";
    *file << "  <h4 class='jd-details-title'>\n";
    *file << "    <span class='sympad'>" << name << "</span>\n";
    *file << "    <span class='normal'>: " << type->getSummary() << "</span>\n";
    *file << "  </h4>\n";

    *file << "  <div class='jd-details-descr'>\n";
    for (auto spec : type->getSpecifications()) {
        writeDetailedTypeSpecification(file, spec);
    }

    writeDeprecatedWarning(file, type);
    if (!generateHtmlParagraphs(file, type->getDescription())) {
        return false;
    }

    *file << "  </div>\n";
    *file << "</div>\n";
    *file << "\n";
    return true;
}

static bool writeDetailedFunction(GeneratedFile* file, Function* function) {
    if (function->hidden()) {
        return true;
    }
    const string& name = function->getName();

    *file << "<a name='android_rs:" << name << "'></a>\n";
    *file << "<div class='jd-details'>\n";
    *file << "  <h4 class='jd-details-title'>\n";
    *file << "    <span class='sympad'>" << name << "</span>\n";
    *file << "    <span class='normal'>: " << function->getSummary() << "</span>\n";
    *file << "  </h4>\n";

    *file << "  <div class='jd-details-descr'>\n";
    map<string, DetailedFunctionEntry> entries;
    if (!getUnifiedFunctionPrototypes(function, &entries)) {
        return false;
    }
    *file << "    <table class='jd-tagtable'><tbody>\n";
    for (auto i : entries) {
        *file << "      <tr>\n";
        *file << "        <td>" << i.second.htmlDeclaration << "</td>\n";
        *file << "        <td>";
        writeHtmlVersionTag(file, i.second.info, true);
        *file << "        </td>\n";
        *file << "      </tr>\n";
    }
    *file << "    </tbody></table>\n";
    *file << "  </div>\n";

    if (function->someParametersAreDocumented()) {
        *file << "  <div class='jd-tagdata'>";
        *file << "    <h5 class='jd-tagtitle'>Parameters</h5>\n";
        *file << "    <table class='jd-tagtable'><tbody>\n";
        for (ParameterEntry* p : function->getParameters()) {
            *file << "    <tr><th>" << p->name << "</th><td>" << p->documentation << "</td></tr>\n";
        }
        *file << "    </tbody></table>\n";
        *file << "  </div>\n";
    }

    string ret = function->getReturnDocumentation();
    if (!ret.empty()) {
        *file << "  <div class='jd-tagdata'>";
        *file << "    <h5 class='jd-tagtitle'>Returns</h5>\n";
        *file << "    <table class='jd-tagtable'><tbody>\n";
        *file << "    <tr><td>" << ret << "</td></tr>\n";
        *file << "    </tbody></table>\n";
        *file << "  </div>\n";
    }

    *file << "  <div class='jd-tagdata jd-tagdescr'>\n";
    writeDeprecatedWarning(file, function);
    if (!generateHtmlParagraphs(file, function->getDescription())) {
        return false;
    }
    *file << "  </div>\n";

    *file << "</div>\n";
    *file << "\n";
    return true;
}

static bool writeDetailedDocumentationFile(const string& directory, const SpecFile& specFile,
                                           bool forVerification) {
    if (!specFile.hasSpecifications()) {
        // This is true for rs_core.spec
        return true;
    }

    GeneratedFile file;
    const string fileName = stringReplace(specFile.getSpecFileName(), ".spec",
                                          forVerification ? ".html" : ".jd");
    if (!file.start(directory, fileName)) {
        return false;
    }
    bool success = true;

    string title = specFile.getBriefDescription();
    writeHeader(&file, forVerification, title);

    file << "<h2>Overview</h2>\n";
    if (!generateHtmlParagraphs(&file, specFile.getFullDescription())) {
        success = false;
    }

    // Write the summary tables.
    file << "<h2>Summary</h2>\n";
    const auto& constants = specFile.getDocumentedConstants();
    const auto& types = specFile.getDocumentedTypes();
    const auto& functions = specFile.getDocumentedFunctions();

    writeSummaryTables(&file, constants, types, functions, NON_DEPRECATED_ONLY, false);
    writeSummaryTables(&file, constants, types, functions, DEPRECATED_ONLY, false);

    // Write the full details of each constant, type, and function.
    if (!constants.empty()) {
        file << "<h2>Constants</h2>\n";
        for (auto i : constants) {
            if (!writeDetailedConstant(&file, i.second)) {
                success = false;
            }
        }
    }
    if (!types.empty()) {
        file << "<h2>Types</h2>\n";
        for (auto i : types) {
            if (!writeDetailedType(&file, i.second)) {
                success = false;
            }
        }
    }
    if (!functions.empty()) {
        file << "<h2>Functions</h2>\n";
        for (auto i : functions) {
            if (!writeDetailedFunction(&file, i.second)) {
                success = false;
            }
        }
    }

    writeFooter(&file, forVerification);
    file.close();

    if (!success) {
        // If in error, write a final message to make it easier to figure out which file failed.
        cerr << fileName << ": Failed due to errors.\n";
    }
    return success;
}

static void generateSnippet(GeneratedFile* file, const string& fileName, const string& title) {
    const char offset[] = "                  ";
    *file << offset << "<li><a href=\"<?cs var:toroot ?>guide/topics/renderscript/reference/"
          << fileName << "\">\n";
    *file << offset << "  <span class=\"en\">" << title << "</span>\n";
    *file << offset << "</a></li>\n";
}

/* Generate a partial file of links that should be cut & pasted into the proper section of the
 * guide_toc.cs file.
 */
static bool generateAndroidTableOfContentSnippet(const string& directory) {
    GeneratedFile file;
    if (!file.start(directory, "guide_toc.cs")) {
        return false;
    }
    file << "<!-- Copy and paste the following lines into the RenderScript section of\n";
    file << "     platform/frameworks/base/docs/html/guide/guide_toc.cs\n\n";

    const char offset[] = "              ";
    file << offset << "<li class=\"nav-section\">\n";
    file << offset << "  <div class=\"nav-section-header\">\n";
    file << offset << "    <a href=\"<?cs var:toroot ?>guide/topics/renderscript/reference/" <<
            OVERVIEW_HTML_FILE_NAME << "\">\n";
    file << offset << "      <span class=\"en\">Runtime API Reference</span>\n";
    file << offset << "    </a></div>\n";
    file << offset << "  <ul>\n";

    for (auto specFile : systemSpecification.getSpecFiles()) {
        if (specFile->hasSpecifications()) {
            const string fileName = stringReplace(specFile->getSpecFileName(), ".spec", ".html");
            generateSnippet(&file, fileName, specFile->getBriefDescription());
        }
    }
    generateSnippet(&file, INDEX_HTML_FILE_NAME, "Index");

    file << offset << "  </ul>\n";
    file << offset << "</li>\n";

    return true;
}

bool generateDocumentation(const string& directory, bool forVerification) {
    bool success = generateOverview(directory, forVerification) &&
                   generateAlphabeticalIndex(directory, forVerification) &&
                   generateAndroidTableOfContentSnippet(directory);
    for (auto specFile : systemSpecification.getSpecFiles()) {
        if (!writeDetailedDocumentationFile(directory, *specFile, forVerification)) {
            success = false;
        }
    }
    return success;
}
