public function generate()
    {
        /** @var LogTable[] $availableLogTables */
        $availableLogTables = array();

        $this->tables->sort();

        foreach ($this->tables as $i => $table) {
            if (is_array($table)) {

                // join condition provided
                $alias = isset($table['tableAlias']) ? $table['tableAlias'] : $table['table'];

                if (isset($table['join'])) {
                    $this->joinString .= ' ' . $table['join'];
                } else {
                    $this->joinString .= ' LEFT JOIN';
                }

                if (!isset($table['joinOn']) && $this->tables->getLogTable($table['table'])) {
                    $logTable = $this->tables->getLogTable($table['table']);
                    if (!empty($availableLogTables)) {
                        $table['joinOn'] = $this->findJoinCriteriasForTables($logTable, $availableLogTables);
                    }
                    if (!isset($table['tableAlias'])) {
                        // eg array('table' => 'log_link_visit_action', 'join' => 'RIGHT JOIN')
                        // we treat this like a regular string table which we can join automatically
                        $availableLogTables[$table['table']] = $logTable;
                    }
                }

                $this->joinString .= ' ' . Common::prefixTable($table['table']) . " AS " . $alias
                                   . " ON " . $table['joinOn'];
                continue;
            }

            $tableSql = Common::prefixTable($table) . " AS $table";

            $logTable = $this->tables->getLogTable($table);

            if ($i == 0) {
                // first table
                $this->joinString .= $tableSql;
            } else {

                $join = $this->findJoinCriteriasForTables($logTable, $availableLogTables);

                if ($join === null) {
                    $availableLogTables[$table] = $logTable;
                    continue;
                }

                // the join sql the default way
                $this->joinString .= " LEFT JOIN $tableSql ON " . $join;
            }

            $availableLogTables[$table] = $logTable;
        }
    }