protected function processRecord($record, $columnMap, &$results, $preview = false)
    {
        if (!is_array($record) || empty($record) || !array_filter($record)) {
            $results->addSkipped("Empty/invalid record data.");
            return;
        }
        //map incoming record according to the standardisation mapping (columnMap)
        $record = $this->columnMapRecord($record);
        //skip if required data is not present
        if (!$this->hasRequiredData($record)) {
            $results->addSkipped("Required data is missing.");
            return;
        }
        $modelClass = $this->objectClass;
        $placeholder = new $modelClass();

        //populate placeholder object with transformed data
        foreach ($this->mappableFields_cache as $field => $label) {
            //skip empty fields
            if (!isset($record[$field]) || empty($record[$field])) {
                continue;
            }
            $this->transformField($placeholder, $field, $record[$field]);
        }
        //find existing duplicate of placeholder data
        $obj = null;
        $existing = null;
        if (!$placeholder->ID && !empty($this->duplicateChecks)) {
            $data = $placeholder->getQueriedDatabaseFields();
            //don't match on ID, ClassName or RecordClassName
            unset($data['ID'], $data['ClassName'], $data['RecordClassName']);
            $existing = $this->findExistingObject($data);
        }
        if ($existing) {
            $obj = $existing;
            $obj->update($data);
        } else {
            // new record
            if (!$this->addNewRecords) {
                $results->addSkipped('New record not added');
                return;
            }
            $obj = $placeholder;
        }

        //callback access to every object
        if (is_callable($this->recordCallback)) {
            $callback  = $this->recordCallback;
            $callback($obj, $record);
        }

        $changed = $existing && $obj->isChanged();
        //try/catch for potential write() ValidationException
        try {
            // write obj record
            $obj->write();

            //publish pages
            if ($this->publishPages && $obj instanceof SiteTree) {
                $obj->publish('Stage', 'Live');
            }

            // save to results
            if ($existing) {
                if ($changed) {
                    $results->addUpdated($obj);
                } else {
                    $results->addSkipped("No data was changed.");
                }
            } else {
                $results->addCreated($obj);
            }
        } catch (ValidationException $e) {
            $results->addSkipped($e->getMessage());
        }

        $objID = $obj->ID;
        // reduce memory usage
        $obj->destroy();
        unset($existingObj);
        unset($obj);
        
        return $objID;
    }