docs: function convertProductionToDiagram(prod, topRuleName) {
          if (prod.type === "NonTerminal") {
              // must handle NonTerminal separately from the other AbstractProductions as we do not want to expand the subDefinition
              // of a reference and cause infinite loops
              return NonTerminal(
                  getNonTerminalName(prod),
                  undefined,
                  prod.occurrenceInParent,
                  topRuleName
              )
          } else if (prod.type !== "Terminal") {
              var subDiagrams = definitionsToSubDiagrams(
                  prod.definition,
                  topRuleName
              )
              if (prod.type === "Rule") {
                  return Diagram.apply(this, subDiagrams)
              } else if (prod.type === "Flat") {
                  return Sequence.apply(this, subDiagrams)
              } else if (prod.type === "Option") {
                  if (subDiagrams.length > 1) {
                      return Optional(Sequence.apply(this, subDiagrams))
                  } else if (subDiagrams.length === 1) {
                      return Optional(subDiagrams[0])
                  } else {
                      throw Error("Empty Optional production, OOPS!")
                  }
              } else if (prod.type === "Repetition") {
                  if (subDiagrams.length > 1) {
                      return ZeroOrMore(Sequence.apply(this, subDiagrams))
                  } else if (subDiagrams.length === 1) {
                      return ZeroOrMore(subDiagrams[0])
                  } else {
                      throw Error("Empty Optional production, OOPS!")
                  }
              } else if (prod.type === "Alternation") {
                  // todo: what does the first argument of choice (the index 0 means?)
                  return Choice.apply(this, [0].concat(subDiagrams))
              } else if (prod.type === "RepetitionMandatory") {
                  if (subDiagrams.length > 1) {
                      return OneOrMore(Sequence.apply(this, subDiagrams))
                  } else if (subDiagrams.length === 1) {
                      return OneOrMore(subDiagrams[0])
                  } else {
                      throw Error("Empty Optional production, OOPS!")
                  }
              } else if (prod.type === "RepetitionWithSeparator") {
                  if (subDiagrams.length > 0) {
                      // MANY_SEP(separator, definition) === (definition (separator definition)*)?
                      return Optional(
                          Sequence.apply(
                              this,
                              subDiagrams.concat([
                                  ZeroOrMore(
                                      Sequence.apply(
                                          this,
                                          [
                                              createTerminalFromSerializedGast(
                                                  prod.separator,
                                                  topRuleName,
                                                  "many_sep"
                                              )
                                          ].concat(subDiagrams)
                                      )
                                  )
                              ])
                          )
                      )
                  } else {
                      throw Error("Empty Optional production, OOPS!")
                  }
              } else if (prod.type === "RepetitionMandatoryWithSeparator") {
                  if (subDiagrams.length > 0) {
                      // AT_LEAST_ONE_SEP(separator, definition) === definition (separator definition)*
                      return Sequence.apply(
                          this,
                          subDiagrams.concat([
                              ZeroOrMore(
                                  Sequence.apply(
                                      this,
                                      [
                                          createTerminalFromSerializedGast(
                                              prod.separator,
                                              topRuleName,
                                              "at_least_one_sep"
                                          )
                                      ].concat(subDiagrams)
                                  )
                              )
                          ])
                      )
                  } else {
                      throw Error("Empty Optional production, OOPS!")
                  }
              }
          } else if (prod.type === "Terminal") {
              return createTerminalFromSerializedGast(
                  prod,
                  topRuleName,
                  "consume"
              )
          } else {
              throw Error("non exhaustive match")
          }
      }