public ImportResult Import(Core.Import import, IImportSource source, bool save)
        {
            var result = new ImportResult
            {
                Date = DateTime.UtcNow,
                File = import.Location,
                Type = import.Type.ToString()
            };

            try
            {
                // build columns
                result.Step = ImportStep.BuildLayout;
                var layout = import.Columns.Select(x =>
                                                   String.IsNullOrEmpty(x.Target)
                            ? (TEnum)Enum.Parse(typeof(TEnum), "None")
                            : (TEnum)Enum.Parse(typeof(TEnum), x.Target)
                                                   ).ToArray();
                result.Layout = layout.Select(x => x.ToString()).ToArray();

                // get data types
                var types = layout.Select(x => GetColumnType(x)).ToArray();

                // validate layout
                result.Step = ImportStep.ValidateLayout;
                var layoutValid = ValidateLayout(layout);
                if (!layoutValid.Success)
                {
                    layoutValid.Problems.Each(x => result.AddProblem(x));
                    return(result);
                }

                // convert all row data
                result.Step = ImportStep.ConvertRowData;
                var rows = source.Select(data => new ImportRow(data, types, layout)).ToList();
                if (rows.Any(x => !x.IsValid))
                {
                    FillRowResults(result, rows);
                    result.AddProblem("Some data could not be converted to the correct format. See row-by-row results for specific problems.");
                    return(result);
                }

                // find existing rows
                result.Step = ImportStep.FindRowEntities;
                Parallel.ForEach(rows, r => r.Entity = Find(r));

                // create missing rows
                result.Step = ImportStep.CreateRowEntities;
                Parallel.ForEach(
                    rows.Where(x => null == x.Entity),
                    r => {
                    r.Entity = Create(r);
                    r.IsNew  = true;
                });

                // validate all row data
                result.Step = ImportStep.ValidateRows;
                foreach (var r in rows)
                {
                    ValidateRow(r);
                }

                // apply all row values
                result.Step = ImportStep.ImportRows;
                Parallel.ForEach(rows, r => Apply(r.Entity, r));
                if (rows.Any(x => !x.IsValid))
                {
                    FillRowResults(result, rows);
                    result.AddProblem("Some data could not be imported into the system. See row-by-row results for specific problems.");
                    return(result);
                }

                // save all records
                if (save)
                {
                    result.Step = ImportStep.SaveRows;
                    Parallel.ForEach(rows, r =>
                    {
                        try
                        {
                            Save(r.Entity);
                        }
                        catch (CouchException ex)
                        {
                            if (ex.Status == (int)HttpStatusCode.Conflict)
                            {
                                // conflicts typically occur when a unique id is supplied for two or more
                                // new rows in an import sheet.. i.e. product id 1234 appears twice, and is new
                                r.AddProblem(
                                    @"There was a conflict saving this record, typically because a unique was duplicated in the spreadsheet.");
                            }
                            else
                            {
                                throw;
                            }
                        }
                    });
                }

                Completed();

                FillRowResults(result, rows);
                result.Step    = ImportStep.Complete;
                result.Success = true;
            }
            catch (Exception ex)
            {
                result.AddProblem(String.Format("ERROR: Import encountered an unexpected error, proces aborted.<br/>Error: {0}<br />Stack: {1}.", (ex.InnerException ?? ex).Message, (ex.InnerException ?? ex).StackTrace));
                if (result.Step == ImportStep.SaveRows)
                {
                    result.AddProblem("DANGER: An error occurred DURING the Save step, meaning that some rows may have been written to the database, and some not. Re-importing this sheet could cause duplication of data.");
                }
            }
            return(result);
        }