public List<API.Common.Model.ChargePoint> Process(CoreReferenceData coreRefData)
        {
            List<ChargePoint> outputList = new List<ChargePoint>();

            var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == 100);//imported and published
            var operationalStatus = coreRefData.StatusTypes.First(os => os.ID == 50);
            var unknownStatus = coreRefData.StatusTypes.First(os => os.ID == 0);
            var usageTypePublic = coreRefData.UsageTypes.First(u => u.ID == 1);
            var usageTypePrivate = coreRefData.UsageTypes.First(u => u.ID == 2);
            var usageTypePrivateForStaffAndVisitors = coreRefData.UsageTypes.First(u => u.ID == 6); //staff and visitors
            var operatorUnknown = coreRefData.Operators.First(opUnknown => opUnknown.ID == 1);

            int itemCount = 0;

            string jsonString = "{ \"data\": " + InputData + "}";

            JObject o = JObject.Parse(jsonString);
            var dataList = o.Values()["list"].Values().ToArray();

            foreach (var item in dataList)
            {
                ChargePoint cp = new ChargePoint();
                cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //AddEnergie
                cp.DataProvidersReference = item["StationID"].ToString();
                cp.DateLastStatusUpdate = DateTime.UtcNow;

                cp.AddressInfo = new AddressInfo();

                cp.AddressInfo.Title = item["ParkName"].ToString();
                cp.AddressInfo.AddressLine1 = item["Address"].ToString().Trim();
                cp.AddressInfo.Town = item["City"].ToString().Trim();
                cp.AddressInfo.StateOrProvince = item["StateOrProvince"].ToString().Trim();
                cp.AddressInfo.Postcode = item["PostalOrZipCode"].ToString().Trim();
                cp.AddressInfo.Latitude = double.Parse(item["Latitude"].ToString());
                cp.AddressInfo.Longitude = double.Parse(item["Longitude"].ToString());

                //default to canada
                cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode.ToLower() == "ca");
                //todo: detect country

                //set network operators
                if (this.SelectedNetworkType == NetworkType.ReseauVER)
                {
                    cp.OperatorInfo = new OperatorInfo { ID = 89 };
                }

                if (this.SelectedNetworkType == NetworkType.LeCircuitElectrique)
                {
                    cp.OperatorInfo = new OperatorInfo { ID = 90 };
                }

                bool isPublic = bool.Parse(item["IsPublic"].ToString());
                if (isPublic)
                {
                    cp.UsageType = usageTypePublic;
                }
                else
                {
                    cp.UsageType = usageTypePrivate;
                }

                cp.NumberOfPoints = int.Parse(item["NumPorts"].ToString());
                cp.StatusType = operationalStatus;

                //populate connectioninfo from Ports
                foreach (var port in item["Ports"].ToArray())
                {
                    ConnectionInfo cinfo = new ConnectionInfo() { };
                    ConnectionType cType = new ConnectionType { ID = 0 };

                    cinfo.Amps = int.Parse(port["Current"].ToString());
                    cinfo.Voltage = int.Parse(port["Voltage"].ToString());
                    cinfo.PowerKW = double.Parse(port["KiloWatts"].ToString());
                    cinfo.Level = new ChargerType() { ID = int.Parse(port["Level"].ToString()) };
                    //cinfo.Comments = (port["Make"]!=null?port["Make"].ToString()+" ":"") + (port["Model"]!=null?port["Model"].ToString():"");

                    if (port["ConnectorType"].ToString() == "J1772")
                    {
                        cType = coreRefData.ConnectionTypes.FirstOrDefault(c => c.ID == 1);
                    }
                    else if (port["ConnectorType"].ToString().ToUpper() == "CHADEMO")
                    {
                        cType = coreRefData.ConnectionTypes.FirstOrDefault(c => c.ID == 2);//CHADEMO
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("Unmatched connector" + port["ConnectorType"].ToString());
                    }

                    cinfo.ConnectionType = cType;

                    if (cp.Connections == null)
                    {
                        cp.Connections = new List<ConnectionInfo>();
                        if (!IsConnectionInfoBlank(cinfo))
                        {
                            cp.Connections.Add(cinfo);
                        }
                    }
                }

                if (cp.DataQualityLevel == null) cp.DataQualityLevel = 4;

                cp.SubmissionStatus = submissionStatus;

                outputList.Add(cp);
                itemCount++;
            }

            return outputList;
        }
        public List<API.Common.Model.ChargePoint> Process(CoreReferenceData coreRefData)
        {
            List<ChargePoint> outputList = new List<ChargePoint>();

            string source = InputData;

            JObject o = JObject.Parse(source);

            var dataList = o["ChargeDevice"].ToArray();

            var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == (int)StandardSubmissionStatusTypes.Imported_UnderReview);//imported and under review
            var submissionStatusDelistedPrivate = coreRefData.SubmissionStatusTypes.First(s => s.ID == (int)StandardSubmissionStatusTypes.Delisted_NotPublicInformation);//delisted not public
            var operationalStatus = coreRefData.StatusTypes.First(os => os.ID == 50);
            var nonoperationalStatus = coreRefData.StatusTypes.First(os => os.ID == 100);
            var unknownStatus = coreRefData.StatusTypes.First(os => os.ID == (int)StandardStatusTypes.Unknown);
            var usageTypeUnknown = coreRefData.UsageTypes.First(u => u.ID == (int)StandardUsageTypes.Unknown);
            var usageTypePublic = coreRefData.UsageTypes.First(u => u.ID == (int)StandardUsageTypes.Public);
            var usageTypePublicPayAtLocation = coreRefData.UsageTypes.First(u => u.ID == (int)StandardUsageTypes.Public_PayAtLocation);
            var usageTypePrivate = coreRefData.UsageTypes.First(u => u.ID == (int)StandardUsageTypes.PrivateRestricted);
            var usageTypePublicMembershipRequired = coreRefData.UsageTypes.First(u => u.ID == (int)StandardUsageTypes.Public_MembershipRequired);
            var operatorUnknown = coreRefData.Operators.First(opUnknown => opUnknown.ID == (int)StandardOperators.UnknownOperator);

            int itemCount = 0;

            foreach (var dataItem in dataList)
            {
                bool skipPOI = false;
                var item = dataItem;
                ChargePoint cp = new ChargePoint();

                var deviceName = item["ChargeDeviceName"].ToString();

                //private addresses are skipped from import
                if (!String.IsNullOrEmpty(deviceName) && deviceName.ToLower().Contains("parkatmyhouse"))
                {
                    //skipPOI = true;
                    skipPOI = true;
                }

                var locationType = item["LocationType"].ToString();
                if (!String.IsNullOrEmpty(locationType))
                {
                    if (locationType.ToLower().Contains("home"))
                    {
                        skipPOI = true;
                    }
                }

                //parse reset of POI data
                cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //UK National Charge Point Registry
                cp.DataProvidersReference = item["ChargeDeviceId"].ToString();
                cp.DateLastStatusUpdate = DateTime.UtcNow;
                cp.AddressInfo = new AddressInfo();

                var locationDetails = item["ChargeDeviceLocation"];
                var addressDetails = locationDetails["Address"];

                cp.AddressInfo.RelatedURL = "";
                cp.DateLastStatusUpdate = DateTime.UtcNow;
                cp.AddressInfo.AddressLine1 = addressDetails["Street"].ToString().Replace("<br>", ", ");
                cp.AddressInfo.Title = String.IsNullOrEmpty(locationDetails["LocationShortDescription"].ToString()) ? cp.AddressInfo.AddressLine1 : locationDetails["LocationShortDescription"].ToString();
                cp.AddressInfo.Title = cp.AddressInfo.Title.Replace("&amp;", "&");
                cp.AddressInfo.Title = cp.AddressInfo.Title.Replace("<br>", ", ");
                if (cp.AddressInfo.Title.Length > 100) cp.AddressInfo.Title = cp.AddressInfo.Title.Substring(0, 64) + "..";
                cp.AddressInfo.Town = addressDetails["PostTown"].ToString();
                string dependantLocality = addressDetails["DependantLocality"].ToString();
                if (!String.IsNullOrEmpty(dependantLocality) && dependantLocality.ToLower() != cp.AddressInfo.Town.ToLower())
                {
                    //use depenendantLocality if provided and is not same as town
                    cp.AddressInfo.AddressLine2 = dependantLocality;
                }
                cp.AddressInfo.Postcode = addressDetails["PostCode"].ToString();
                cp.AddressInfo.Latitude = double.Parse(locationDetails["Latitude"].ToString());
                cp.AddressInfo.Longitude = double.Parse(locationDetails["Longitude"].ToString());
                cp.AddressInfo.AccessComments = locationDetails["LocationLongDescription"].ToString().Replace("<br>", ", ").Replace("\r\n", ", ").Replace("\n", ", ");

                //if(!String.IsNullOrEmpty(cp.AddressInfo.Postcode))
                //{
                //cp.AddressInfo.Postcode = this.NormalizePostcode(cp.AddressInfo.Postcode);
                //}
                //TODO: if address wasn't provide in address details try to parse from "LocationLongDescription":
                /*if (String.IsNullOrEmpty(cp.AddressInfo.AddressLine1) && string.IsNullOrEmpty(cp.AddressInfo.AddressLine2) && string.IsNullOrEmpty(cp.AddressInfo.Town) && string.IsNullOrEmpty(cp.AddressInfo.Postcode))
                {
                }*/

                //if title is empty, attempt to add a suitable replacement
                if (String.IsNullOrEmpty(cp.AddressInfo.Title))
                {
                    if (!String.IsNullOrEmpty(cp.AddressInfo.AddressLine1))
                    {
                        cp.AddressInfo.Title = cp.AddressInfo.AddressLine1;
                    }
                    else
                    {
                        cp.AddressInfo.Title = cp.AddressInfo.Postcode;
                    }
                }
                //cp.AddressInfo.ContactTelephone1 = item["phone"].ToString();

                if (!String.IsNullOrEmpty(addressDetails["Country"].ToString()))
                {
                    string country = addressDetails["Country"].ToString();
                    int? countryID = null;

                    var countryVal = coreRefData.Countries.FirstOrDefault(c => c.Title.ToLower() == country.Trim().ToLower());
                    if (countryVal == null)
                    {
                        country = country.ToUpper();
                        //match country
                        if (country == "gb" || country == "US" || country == "USA" || country == "U.S." || country == "U.S.A.") countryID = 2;
                        if (country == "UK" || country == "GB" || country == "GREAT BRITAIN" || country == "UNITED KINGDOM") countryID = 1;
                    }
                    else
                    {
                        countryID = countryVal.ID;
                    }

                    if (countryID == null)
                    {
                        this.Log("Country Not Matched, will require Geolocation:" + item["country"].ToString());
                    }
                    else
                    {
                        cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(cy => cy.ID == countryID);
                    }
                }
                else
                {
                    //default to US if no country identified
                    //cp.AddressInfo.Country = cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(cy => cy.ID == 2);
                }

                //operator from DeviceController
                var deviceController = item["DeviceController"];

                cp.AddressInfo.RelatedURL = deviceController["Website"].ToString();
                var deviceOperator = coreRefData.Operators.FirstOrDefault(devOp => devOp.Title.Contains(deviceController["OrganisationName"].ToString()));
                if (deviceOperator != null)
                {
                    cp.OperatorInfo = deviceOperator;
                }
                else
                {
                    //operator from device owner
                    var devOwner = item["DeviceOwner"];
                    deviceOperator = coreRefData.Operators.FirstOrDefault(devOp => devOp.Title.Contains(devOwner["OrganisationName"].ToString()));
                    if (deviceOperator != null)
                    {
                        cp.OperatorInfo = deviceOperator;
                    }
                }

                //determine most likely usage type
                cp.UsageType = usageTypeUnknown;

                if (item["SubscriptionRequiredFlag"].ToString().ToUpper() == "TRUE")
                {
                    //membership required
                    cp.UsageType = usageTypePublicMembershipRequired;
                }
                else
                {
                    if (item["PaymentRequiredFlag"].ToString().ToUpper() == "TRUE")
                    {
                        //payment required
                        cp.UsageType = usageTypePublicPayAtLocation;
                    }
                    else
                    {
                        //accessible 24 hours, payment not required and membership not required, assume public
                        if (item["Accessible24Hours"].ToString().ToUpper() == "TRUE")
                        {
                            cp.UsageType = usageTypePublic;
                        }
                    }
                }

                //special usage cases detected from text
                if (cp.AddressInfo.ToString().ToLower().Contains("no public access"))
                {
                    cp.UsageType = usageTypePrivate;
                }

                //add connections
                var connectorList = item["Connector"].ToArray();
                foreach (var conn in connectorList)
                {
                    string connectorType = conn["ConnectorType"].ToString();
                    if (!String.IsNullOrEmpty(connectorType))
                    {
                        ConnectionInfo cinfo = new ConnectionInfo() { };
                        ConnectionType cType = new ConnectionType { ID = 0 };
                        ChargerType level = null;
                        cinfo.Reference = conn["ConnectorId"].ToString();

                        if (connectorType.ToUpper().Contains("BS 1363") || connectorType.ToUpper().Contains("3-PIN TYPE G (BS1363)"))
                        {
                            cType = new ConnectionType();
                            cType.ID = 3; //UK 13 amp plug
                            level = new ChargerType { ID = 2 };//default to level 2
                        }

                        if (connectorType.ToUpper() == "IEC 62196-2 TYPE 1 (SAE J1772)" || connectorType.ToUpper() == "TYPE 1 SAEJ1772 (IEC 62196)")
                        {
                            cType = new ConnectionType();
                            cType.ID = 1; //J1772
                            level = new ChargerType { ID = 2 };//default to level 2
                        }

                        if (connectorType.ToUpper() == "IEC 62196-2 TYPE 2" || connectorType.ToUpper().Contains("TYPE 2 MENNEKES (IEC62196)"))
                        {
                            cType = new ConnectionType();
                            cType.ID = 25; //Mennkes Type 2
                            level = new ChargerType { ID = 2 };//default to level 2
                        }

                        if (connectorType.ToUpper() == "JEVS G 105 (CHADEMO)" || connectorType.ToUpper() == "JEVS G105 (CHADEMO) DC")
                        {
                            cType = new ConnectionType();
                            cType.ID = 2; //CHadeMO
                            level = new ChargerType { ID = 3 };//default to level 3
                        }
                        if (connectorType.ToUpper() == "IEC 62196-2 TYPE 3")
                        {
                            cType = new ConnectionType();
                            cType.ID = 26; //IEC 62196-2 type 3

                            level = new ChargerType { ID = 2 };//default to level 2
                        }

                        if (connectorType.ToUpper() == "TYPE 2 COMBO (IEC62196) DC")
                        {
                            cType = new ConnectionType();
                            cType.ID = 33; //CCS with Type 2

                            level = new ChargerType { ID = 3 };//default to level 3
                        }

                        if (cType.ID == 0)
                        {
                            var conType = coreRefData.ConnectionTypes.FirstOrDefault(ct => ct.Title.ToLower().Contains(conn.ToString().ToLower()));
                            if (conType != null) cType = conType;
                        }

                        if (!String.IsNullOrEmpty(conn["RatedOutputVoltage"].ToString())) cinfo.Voltage = int.Parse(conn["RatedOutputVoltage"].ToString());
                        if (!String.IsNullOrEmpty(conn["RatedOutputCurrent"].ToString())) cinfo.Amps = int.Parse(conn["RatedOutputCurrent"].ToString());
                        //TODO: use AC/DC/3 Phase data

                        if (conn["ChargePointStatus"] != null)
                        {
                            cinfo.StatusType = operationalStatus;
                            if (conn["ChargePointStatus"].ToString() == "Out of service") cinfo.StatusType = nonoperationalStatus;
                        }

                        if (conn["RatedOutputkW"] != null)
                        {
                            double tmpKw = 0;
                            if (double.TryParse(conn["RatedOutputkW"].ToString(), out tmpKw))
                            {
                                cinfo.PowerKW = tmpKw;
                            }
                        }

                        if (conn["RatedOutputVoltage"] != null)
                        {
                            int tmpV = 0;
                            if (int.TryParse(conn["RatedOutputVoltage"].ToString(), out tmpV))
                            {
                                cinfo.Voltage = tmpV;
                            }
                        }

                        if (conn["RatedOutputCurrent"] != null)
                        {
                            int tmpA = 0;
                            if (int.TryParse(conn["RatedOutputCurrent"].ToString(), out tmpA))
                            {
                                cinfo.Amps = tmpA;
                            }
                        }

                        if (conn["ChargeMethod"] != null && !String.IsNullOrEmpty(conn["ChargeMethod"].ToString()))
                        {
                            string method = conn["ChargeMethod"].ToString();
                            //Single Phase AC, Three Phase AC, DC
                            if (method == "Single Phase AC") cinfo.CurrentTypeID = (int)StandardCurrentTypes.SinglePhaseAC;
                            if (method == "Three Phase AC") cinfo.CurrentTypeID = (int)StandardCurrentTypes.ThreePhaseAC;
                            if (method == "DC") cinfo.CurrentTypeID = (int)StandardCurrentTypes.DC;
                        }
                        cinfo.ConnectionType = cType;
                        cinfo.Level = level;

                        if ((cinfo.ConnectionType == null && cinfo.ConnectionTypeID == null) || cinfo.ConnectionType != null && cinfo.ConnectionType.ID == 0)
                        {
                            if (!String.IsNullOrEmpty(connectorType))
                            {
                                Log("Unknown connector type:" + connectorType);
                            }
                        }
                        if (cp.Connections == null)
                        {
                            cp.Connections = new List<ConnectionInfo>();
                            if (!IsConnectionInfoBlank(cinfo))
                            {
                                //TODO: skip items with blank address info
                                cp.Connections.Add(cinfo);
                            }
                        }
                    }
                }

                //apply data attribution metadata
                if (cp.MetadataValues == null) cp.MetadataValues = new List<MetadataValue>();
                cp.MetadataValues.Add(new MetadataValue { MetadataFieldID = (int)StandardMetadataFields.Attribution, ItemValue = DataAttribution });

                if (cp.DataQualityLevel == null) cp.DataQualityLevel = 3;

                if (cp.SubmissionStatus == null) cp.SubmissionStatus = submissionStatus;

                if (!skipPOI)
                {
                    outputList.Add(cp);
                    itemCount++;
                }
            }

            return outputList;
        }
        public List<API.Common.Model.ChargePoint> Process(CoreReferenceData coreRefData)
        {
            List<ChargePoint> outputList = new List<ChargePoint>();

            string source = InputData;

            JObject o = JObject.Parse(source);

            var dataList = o["locations"].ToArray();

            var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == (int)StandardSubmissionStatusTypes.Imported_UnderReview);//imported and under review
            var operationalStatus = coreRefData.StatusTypes.First(os => os.ID == 50);
            var unknownStatus = coreRefData.StatusTypes.First(os => os.ID == 0);
            var usageTypePublic = coreRefData.UsageTypes.First(u => u.ID == 1);
            var usageTypePrivate = coreRefData.UsageTypes.First(u => u.ID == 2);
            var operatorUnknown = coreRefData.Operators.First(opUnknown => opUnknown.ID == 1);

            int itemCount = 0;
            foreach (var item in dataList)
            {
                ChargePoint cp = new ChargePoint();
                cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //carstations.com
                cp.DataProvidersReference = item["post_id"].ToString();
                cp.DateLastStatusUpdate = DateTime.UtcNow;
                cp.AddressInfo = new AddressInfo();

                //carstations.com have requested we not use the station names from their data, so we use address
                //cp.AddressInfo.Title = item["name"] != null ? item["name"].ToString() : item["address"].ToString();
                cp.AddressInfo.Title = item["address"] != null ? item["address"].ToString() : item["post_id"].ToString();
                cp.AddressInfo.Title = cp.AddressInfo.Title.Trim().Replace("&amp;", "&");
                cp.AddressInfo.RelatedURL = "http://carstations.com/" + cp.DataProvidersReference;
                cp.DateLastStatusUpdate = DateTime.UtcNow;
                cp.AddressInfo.AddressLine1 = item["address"].ToString().Trim();
                cp.AddressInfo.Town = item["city"].ToString().Trim();
                cp.AddressInfo.StateOrProvince = item["region"].ToString().Trim();
                cp.AddressInfo.Postcode = item["postal_code"].ToString().Trim();
                cp.AddressInfo.Latitude = double.Parse(item["latitude"].ToString().Trim());
                cp.AddressInfo.Longitude = double.Parse(item["longitude"].ToString().Trim());

                cp.AddressInfo.ContactTelephone1 = item["phone"].ToString();

                if (!String.IsNullOrEmpty(item["country"].ToString()))
                {
                    string country = item["country"].ToString();
                    int? countryID = null;

                    var countryVal = coreRefData.Countries.FirstOrDefault(c => c.Title.ToLower() == country.Trim().ToLower());
                    if (countryVal == null)
                    {
                        country = country.ToUpper();
                        //match country
                        if (country == "UNITED STATES" || country == "US" || country == "USA" || country == "U.S." || country == "U.S.A.") countryID = 2;

                        if (country == "UK" || country == "GB" || country == "GREAT BRITAIN" || country == "UNITED KINGDOM") countryID = 1;
                    }
                    else
                    {
                        countryID = countryVal.ID;
                    }

                    if (countryID == null)
                    {
                        this.Log("Country Not Matched, will require Geolocation:" + item["country"].ToString());
                    }
                    else
                    {
                        cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(cy => cy.ID == countryID);
                    }
                }
                else
                {
                    //default to US if no country identified
                    //cp.AddressInfo.Country = cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(cy => cy.ID == 2);
                }

                //System.Diagnostics.Debug.WriteLine(item.ToString());
                string publicCount = item["public"].ToString();
                string privateCount = item["private"].ToString();

                if (!String.IsNullOrEmpty(publicCount) && publicCount != "0")
                {
                    try
                    {
                        cp.NumberOfPoints = int.Parse(publicCount);
                    }
                    catch (Exception) { }
                    cp.UsageType = usageTypePublic;
                }
                else
                {
                    if (!String.IsNullOrEmpty(privateCount) && privateCount != "0")
                    {
                        try
                        {
                            cp.NumberOfPoints = int.Parse(privateCount);
                        }
                        catch (Exception) { }
                        cp.UsageType = usageTypePrivate;
                    }
                }

                string verifiedFlag = item["verified_flag"].ToString();

                if (!string.IsNullOrEmpty(verifiedFlag) && verifiedFlag != "0")
                {
                    cp.StatusType = operationalStatus;
                }
                else
                {
                    cp.StatusType = unknownStatus;
                }

                //TODO: allow for multiple operators?
                var operatorsNames = item["brands"].ToArray();

                if (operatorsNames.Count() > 0)
                {
                    var operatorName = operatorsNames[0].ToString();
                    var opDetails = coreRefData.Operators.FirstOrDefault(op => op.Title.ToLower().Contains(operatorName.ToString().ToLower()));
                    if (opDetails != null)
                    {
                        cp.OperatorInfo = opDetails;
                    }
                    else
                    {
                        Log("Operator not matched:" + operatorName);
                    }
                }
                else
                {
                    cp.OperatorInfo = operatorUnknown;
                }

                var connectorTypes = item["techs"].ToArray();
                foreach (var conn in connectorTypes)
                {
                    ConnectionInfo cinfo = new ConnectionInfo() { };
                    ConnectionType cType = new ConnectionType { ID = 0 };
                    ChargerType level = null;
                    cinfo.Reference = conn.ToString();

                    if (conn.ToString().ToUpper() == "J1772")
                    {
                        cType = new ConnectionType();
                        cType.ID = 1; //J1772
                        level = new ChargerType { ID = 2 };//default to level 2
                    }

                    if (conn.ToString().ToUpper() == "CHADEMO")
                    {
                        cType = new ConnectionType();
                        cType.ID = 2; //CHadeMO
                        level = new ChargerType { ID = 3 };//default to level 3
                    }
                    if (conn.ToString().ToUpper() == "NEMA5")
                    {
                        cType = new ConnectionType();
                        cType.ID = 9; //NEMA5-20R
                        level = new ChargerType { ID = 1 };//default to level 1
                    }

                    if (cType.ID == 0)
                    {
                        var conType = coreRefData.ConnectionTypes.FirstOrDefault(ct => ct.Title.ToLower().Contains(conn.ToString().ToLower()));
                        if (conType != null) cType = conType;
                    }
                    cinfo.ConnectionType = cType;
                    cinfo.Level = level;

                    if (cp.Connections == null)
                    {
                        cp.Connections = new List<ConnectionInfo>();
                        if (!IsConnectionInfoBlank(cinfo))
                        {
                            cp.Connections.Add(cinfo);
                        }
                    }
                }

                if (cp.DataQualityLevel == null) cp.DataQualityLevel = 2;

                cp.SubmissionStatus = submissionStatus;

                if (IsPOIValidForImport(cp))
                {
                    outputList.Add(cp);
                }

                itemCount++;
            }

            return outputList;
        }
        public List<API.Common.Model.ChargePoint> Process(CoreReferenceData coreRefData)
        {
            List<ChargePoint> outputList = new List<ChargePoint>();

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(InputData);

            XmlNodeList dataList = xmlDoc.SelectNodes("//chargerstation");

            var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == 100);//imported and published
            var operationalStatus = coreRefData.StatusTypes.First(os => os.ID == 50);
            var unknownStatus = coreRefData.StatusTypes.First(os => os.ID == 0);
            var usageTypePublic = coreRefData.UsageTypes.First(u => u.ID == 1);
            var usageTypePrivate = coreRefData.UsageTypes.First(u => u.ID == 2);
            var usageTypePrivateForStaffAndVisitors = coreRefData.UsageTypes.First(u => u.ID == 6); //staff and visitors
            var operatorUnknown = coreRefData.Operators.First(opUnknown => opUnknown.ID == 1);

            int itemCount = 0;
            foreach (XmlNode chargerstation in dataList)
            {
                var item = chargerstation.SelectNodes("metadata").Item(0);
                ChargePoint cp = new ChargePoint();
                cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //nobil.no
                cp.DataProvidersReference = item["id"].InnerText; //is id unique across countries?
                cp.DateLastStatusUpdate = DateTime.UtcNow;
                cp.AddressInfo = new AddressInfo();

                cp.AddressInfo.Title = item["name"].InnerText != null ? item["name"].InnerText : item["Street"].InnerText;
                cp.AddressInfo.Title = cp.AddressInfo.Title.Trim().Replace("&amp;", "&");
                //cp.AddressInfo.RelatedURL = item["url"].ToString();

                cp.DateLastStatusUpdate = DateTime.UtcNow;
                cp.AddressInfo.AddressLine1 = item["Street"].InnerText;
                if (item["House_number"] != null) cp.AddressInfo.AddressLine1 += " " + item["House_number"].InnerText;
                cp.AddressInfo.Town = item["City"].InnerText.Trim();
                cp.AddressInfo.StateOrProvince = item["County"].InnerText.Trim();
                cp.AddressInfo.Postcode = item["Zipcode"].InnerText.Trim();
                string posString = item["Position"].InnerText.Trim();

                int sepPos = posString.IndexOf(",") - 1;
                string lat = posString.Substring(1, sepPos);
                sepPos += 2;
                string lon = posString.Substring(sepPos, (posString.Length - sepPos) - 1);
                cp.AddressInfo.Latitude = double.Parse(lat);
                cp.AddressInfo.Longitude = double.Parse(lon);

                //default to norway
                var countryCode = item["Land_code"].InnerText;
                if (countryCode.ToUpper() == "NOR")
                {
                    cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode.ToLower() == "no");
                }
                else if (countryCode.ToUpper() == "FIN")
                {
                    cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode.ToLower() == "fi");
                }
                else if (countryCode.ToUpper() == "SWE")
                {
                    cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode.ToLower() == "se");
                }
                else if (countryCode.ToUpper() == "DAN")
                {
                    cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode.ToLower() == "dk");
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("Unknown country code:" + countryCode);
                }

                cp.AddressInfo.AccessComments = item["Description_of_location"].InnerText;
                cp.AddressInfo.GeneralComments = item["Contact_info"].InnerText;

                cp.NumberOfPoints = int.Parse(item["Number_charging_points"].InnerText);

                var attributes = chargerstation.SelectNodes("attributes").Item(0);
                var connectors = attributes.SelectSingleNode("connectors").SelectNodes("connector");
                foreach (XmlNode connector in connectors)
                {
                    var connectorAttribs = connector.SelectSingleNode("attribute[attrtypeid=4]");
                    var chargingCapacityAttribs = connector.SelectSingleNode("attribute[attrtypeid=5]");
                    var chargingModeAttribs = connector.SelectSingleNode("attribute[attrtypeid=20]");
                    ConnectionInfo cinfo = new ConnectionInfo() { };
                    cinfo.Reference = connector.Attributes["id"].InnerText;

                    ConnectionType cType = new ConnectionType { ID = 0 };
                    if (connectorAttribs != null)
                    {
                        var connectorTypeVal = connectorAttribs.SelectSingleNode("attrvalid").InnerText;
                        if (connectorTypeVal == "14")
                        {
                            cType.ID = 28;// Schuko CEE 7/4
                        }
                        else if (connectorTypeVal == "40")
                        {
                            cType.ID = 27;// tesla supercharger connnector
                        }
                        else if (connectorTypeVal == "31")
                        {
                            //type 1 == J1772?
                            cType.ID = (int)StandardConnectionTypes.J1772;
                        }
                        else if (connectorTypeVal == "29")
                        {
                            cType.ID = 8;// tesla roadster
                        }
                        else if (connectorTypeVal == "32")
                        {
                            cType.ID = 25;// type 2 (mennekes)
                        }
                        else if (connectorTypeVal == "50")
                        {
                            cType.ID = 28;// type 2 + schuko both present?
                        }
                        else if (connectorTypeVal == "30")
                        {
                            cType.ID = (int)StandardConnectionTypes.CHAdeMO;
                        }
                        else if (connectorTypeVal == "34")
                        {
                            cType.ID = 34;//IEC 60309 3 pin
                        }
                        else if (connectorTypeVal == "36")
                        {
                            cType.ID = 35;//IEC 60309 5 pin
                        }
                        else if (connectorTypeVal == "39")
                        {
                            cType.ID = 33;//Type 2 of CCS coupler
                        }
                        else if (connectorTypeVal == "41")
                        {
                            cType.ID = (int)StandardConnectionTypes.CHAdeMO;//CCS combo + Chademo both present
                        }
                        else if (connectorTypeVal == "43")
                        {
                            cType.ID = (int)StandardConnectionTypes.CHAdeMO;//CHAdeMO + Combo + AC-Type2 all present
                        }
                        else if (connectorTypeVal == "0")
                        {
                            cType.ID = 0;//unknown
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("Unnknown connectorDetails: " + connectorAttribs.InnerText);
                        }
                    }

                    if (chargingCapacityAttribs != null)
                    {
                        //TODO: 3-Phase power calcs are wrong.
                        var connectorTypeVal = chargingCapacityAttribs.SelectSingleNode("attrvalid").InnerText;
                        if (connectorTypeVal == "7")
                        {
                            cinfo.Amps = 16;
                            cinfo.Voltage = 230;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.SinglePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 2 }; //default to lvl2
                        }
                        else if (connectorTypeVal == "8")
                        {
                            cinfo.Amps = 32;
                            cinfo.Voltage = 230;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.SinglePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 2 }; //default to lvl2
                        }
                        else if (connectorTypeVal == "10")
                        {
                            cinfo.Amps = 16;
                            cinfo.Voltage = 400;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.ThreePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 2 }; //default to lvl2
                        }
                        else if (connectorTypeVal == "11")
                        {
                            //500V DC
                            cinfo.Amps = 200;
                            cinfo.Voltage = 500;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "12")
                        {
                            //400V AC (3 Phase) 63A
                            cinfo.Amps = 63;
                            cinfo.Voltage = 400;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.ThreePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "13")
                        {
                            //tesla super charger
                            cinfo.Amps = 200;
                            cinfo.Voltage = 500;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "16")
                        {
                            cinfo.Amps = 16;
                            cinfo.Voltage = 230;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.ThreePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 2 }; //default to lvl2
                        }
                        else if (connectorTypeVal == "17")
                        {
                            cinfo.Amps = 32;
                            cinfo.Voltage = 230;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.ThreePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 2 }; //default to lvl2
                        }
                        else if (connectorTypeVal == "19")
                        {
                            //500V DC MAX 50A
                            cinfo.Amps = 50;
                            cinfo.Voltage = 500;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "20")
                        {
                            //TODO: 500VDC max 200A + 400V 3-phase max 63A
                            cinfo.Amps = 200;
                            cinfo.Voltage = 500;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "22")
                        {
                            //480VDC max 270A
                            cinfo.Amps = 270;
                            cinfo.Voltage = 480;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "27")
                        {
                            //tesla super charger
                            cinfo.Amps = 200;
                            cinfo.Voltage = 500;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "0")
                        {
                            //unknown power level
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("unknown chargingCapacity: " + chargingCapacityAttribs.InnerText);
                        }
                    }

                    if (cinfo.Amps > 0 && cinfo.Voltage > 0)
                    {
                        cinfo.PowerKW = (cinfo.Amps * cinfo.Voltage / 1000);
                    }

                    cinfo.ConnectionType = cType;

                    if (chargingModeAttribs != null)
                    {
                        var chargeMode = chargingModeAttribs.SelectSingleNode("trans");
                        if (chargeMode != null)
                        {
                            cinfo.Comments = chargeMode.InnerText;
                        }
                    }
                    if (cp.Connections == null)
                    {
                        cp.Connections = new List<ConnectionInfo>();
                        if (!IsConnectionInfoBlank(cinfo))
                        {
                            cp.Connections.Add(cinfo);
                        }
                    }
                }

                if (cp.DataQualityLevel == null) cp.DataQualityLevel = 2;

                cp.SubmissionStatus = submissionStatus;

                outputList.Add(cp);
                itemCount++;
            }

            return outputList;
        }