From f731117cb120ba0620c35c37679365959286419d Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Thu, 22 Sep 2016 08:34:43 +0200
Subject: [PATCH] extending validation from GUI, using default values for
 reading user input, adding validation to gear dialog and axle dialog

---
 VECTO/GUI/EngineForm.vb        | 103 ++++----
 VECTO/GUI/GearboxForm.vb       | 165 ++++++------
 VECTO/GUI/GearboxGearDialog.vb |  63 ++++-
 VECTO/GUI/VectoJobForm.vb      | 452 +++++++++++++++++----------------
 VECTO/GUI/VehicleAxleDialog.vb |  33 ++-
 VECTO/GUI/VehicleForm.vb       |  26 +-
 VECTO/Input Files/Engine.vb    |  21 +-
 VECTO/Input Files/Gearbox.vb   |  40 ++-
 VECTO/Input Files/VectoJob.vb  |  19 +-
 VECTO/Input Files/Vehicle.vb   |  30 ++-
 10 files changed, 543 insertions(+), 409 deletions(-)

diff --git a/VECTO/GUI/EngineForm.vb b/VECTO/GUI/EngineForm.vb
index f125b692e7..e041ee0857 100644
--- a/VECTO/GUI/EngineForm.vb
+++ b/VECTO/GUI/EngineForm.vb
@@ -13,6 +13,8 @@ Imports TUGraz.VectoCore.InputData.Reader
 Imports TUGraz.VectoCore.Models.Declaration
 Imports TUGraz.VectoCore.Models.SimulationComponent.Data
 Imports TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
+Imports TUGraz.VectoCore.Utils
+Imports VectoAuxiliaries
 ' Copyright 2014 European Union.
 ' Licensed under the EUPL (the 'Licence');
 '
@@ -214,9 +216,9 @@ Public Class EngineForm
 
 		engine.ModelName = TbName.Text
 		If Trim(engine.ModelName) = "" Then engine.ModelName = "Undefined"
-		engine.Displacement = TbDispl.Text.ToDouble()
-		engine.EngineInertia = TbInertia.Text.ToDouble()
-		engine.IdleSpeed = TbNleerl.Text.ToDouble()
+		engine.Displacement = TbDispl.Text.ToDouble(0)
+		engine.EngineInertia = TbInertia.Text.ToDouble(0)
+		engine.IdleSpeed = TbNleerl.Text.ToDouble(0)
 
 		engine.PathFld = TbFLD.Text
 		engine.PathMap = TbMAP.Text
@@ -356,73 +358,68 @@ Public Class EngineForm
 	End Sub
 
 	Private Sub UpdatePic()
-
-		'Dim fldOK As Boolean = False
-		'Dim mapOK As Boolean = False
 		Dim fullLoadCurve As FullLoadCurve = Nothing
 		Dim fcMap As FuelConsumptionMap = Nothing
-		Dim chart As Chart
-		Dim series As Series
-		Dim chartArea As ChartArea
-		Dim img As Bitmap
-		Dim engine As IEngineEngineeringInputData = Nothing
+
 
 		PicBox.Image = Nothing
 
-		If Not File.Exists(_engFile) Then Exit Sub
+		'If Not File.Exists(_engFile) Then Exit Sub
 
 		Try
-
-			'Read Files
-			Dim inputData As IEngineeringInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(_engFile), 
-																	IEngineeringInputDataProvider)
-			engine = inputData.EngineInputData
-			fullLoadCurve = FullLoadCurveReader.Create(engine.FullLoadCurve, engineFld:=True)
-			fcMap = FuelConsumptionMapReader.Create(engine.FuelConsumptionMap)
-
+			Dim fldFile As String =
+					If(Not String.IsNullOrWhiteSpace(_engFile), Path.Combine(Path.GetDirectoryName(_engFile), TbFLD.Text), TbFLD.Text)
+			fullLoadCurve = FullLoadCurveReader.Create(VectoCSVFile.Read(fldFile), engineFld:=True)
 		Catch ex As Exception
+		End Try
 
+		Try
+			Dim fcFile As String =
+					If(Not String.IsNullOrWhiteSpace(_engFile), Path.Combine(Path.GetDirectoryName(_engFile), TbMAP.Text), TbMAP.Text)
+			fcMap = FuelConsumptionMapReader.Create(VectoCSVFile.Read(fcFile))
+		Catch ex As Exception
 		End Try
 
-		If fullLoadCurve Is Nothing OrElse engine Is Nothing OrElse fcMap Is Nothing Then Exit Sub
+		If fullLoadCurve Is Nothing AndAlso fcMap Is Nothing Then Exit Sub
 
 
 		'Create plot
-		chart = New Chart
+		Dim chart As Chart = New Chart
 		chart.Width = PicBox.Width
 		chart.Height = PicBox.Height
 
-		chartArea = New ChartArea
-
-
-		series = New Series
-		series.Points.DataBindXY(fullLoadCurve.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
-								fullLoadCurve.FullLoadEntries.Select(Function(x) x.TorqueFullLoad.Value()).ToArray())
-		series.ChartType = SeriesChartType.FastLine
-		series.BorderWidth = 2
-		series.Color = Color.DarkBlue
-		series.Name = "Full load (" & Path.GetFileNameWithoutExtension(engine.FullLoadCurve.Source) & ")"
-		chart.Series.Add(series)
-
-		series = New Series
-		series.Points.DataBindXY(fullLoadCurve.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
-								fullLoadCurve.FullLoadEntries.Select(Function(x) x.TorqueDrag.Value()).ToArray())
-		series.ChartType = SeriesChartType.FastLine
-		series.BorderWidth = 2
-		series.Color = Color.Blue
-		series.Name = "Motoring (" & Path.GetFileNameWithoutExtension(engine.FullLoadCurve.Source) & ")"
-		chart.Series.Add(series)
-
-
-		series = New Series
-		series.Points.DataBindXY(fcMap.Entries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
-								fcMap.Entries.Select(Function(x) x.Torque.Value()).ToArray())
-		series.ChartType = SeriesChartType.Point
-		series.MarkerSize = 3
-		series.Color = Color.Red
-		series.Name = "Map"
-		chart.Series.Add(series)
+		Dim chartArea As ChartArea = New ChartArea
+
+		If Not fullLoadCurve Is Nothing Then
+			Dim series As Series = New Series
+			series.Points.DataBindXY(fullLoadCurve.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
+									fullLoadCurve.FullLoadEntries.Select(Function(x) x.TorqueFullLoad.Value()).ToArray())
+			series.ChartType = SeriesChartType.FastLine
+			series.BorderWidth = 2
+			series.Color = Color.DarkBlue
+			series.Name = "Full load (" & TbFLD.Text & ")"
+			chart.Series.Add(series)
+
+			series = New Series
+			series.Points.DataBindXY(fullLoadCurve.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
+									fullLoadCurve.FullLoadEntries.Select(Function(x) x.TorqueDrag.Value()).ToArray())
+			series.ChartType = SeriesChartType.FastLine
+			series.BorderWidth = 2
+			series.Color = Color.Blue
+			series.Name = "Motoring (" & Path.GetFileNameWithoutExtension(TbMAP.Text) & ")"
+			chart.Series.Add(series)
+		End If
 
+		If Not fcMap Is Nothing Then
+			Dim series As Series = New Series
+			series.Points.DataBindXY(fcMap.Entries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
+									fcMap.Entries.Select(Function(x) x.Torque.Value()).ToArray())
+			series.ChartType = SeriesChartType.Point
+			series.MarkerSize = 3
+			series.Color = Color.Red
+			series.Name = "Map"
+			chart.Series.Add(series)
+		End If
 
 		chartArea.Name = "main"
 
@@ -448,7 +445,7 @@ Public Class EngineForm
 
 		chart.Update()
 
-		img = New Bitmap(chart.Width, chart.Height, PixelFormat.Format32bppArgb)
+		Dim img As Bitmap = New Bitmap(chart.Width, chart.Height, PixelFormat.Format32bppArgb)
 		chart.DrawToBitmap(img, New Rectangle(0, 0, PicBox.Width, PicBox.Height))
 
 
diff --git a/VECTO/GUI/GearboxForm.vb b/VECTO/GUI/GearboxForm.vb
index ec985dcc99..851ee73589 100644
--- a/VECTO/GUI/GearboxForm.vb
+++ b/VECTO/GUI/GearboxForm.vb
@@ -186,15 +186,19 @@ Public Class GearboxForm
 
 		LvGears.Items.Clear()
 
-		LvGears.Items.Add(CreateListviewItem("Axle", 0, "0", "", ""))
+		LvGears.Items.Add(CreateListviewItem("Axle", 1, "1", "", ""))
 
 		'Me.ChSkipGears.Checked = False         'set by CbGStype.SelectedIndexChanged
 		'Me.ChShiftInside.Checked = False       'set by CbGStype.SelectedIndexChanged
-		TbTqResv.Text = ""
-		TbShiftTime.Text = ""
-		TbTqResvStart.Text = ""
-		TbStartSpeed.Text = ""
-		TbStartAcc.Text = ""
+		TbTqResv.Text = DeclarationData.Gearbox.TorqueReserve.ToGUIFormat()
+		TbShiftTime.Text = DeclarationData.Gearbox.MinTimeBetweenGearshifts.ToGUIFormat()
+		TbTqResvStart.Text = DeclarationData.Gearbox.TorqueReserveStart.ToGUIFormat()
+		TbStartSpeed.Text = DeclarationData.Gearbox.StartSpeed.ToGUIFormat() ' in m/s!
+		TbStartAcc.Text = DeclarationData.Gearbox.StartAcceleration.ToGUIFormat()
+
+		tbUpshiftMinAcceleration.Text = DeclarationData.Gearbox.UpshiftMinAcceleration.ToGUIFormat()
+		tbDownshiftAfterUpshift.Text = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay.ToGUIFormat()
+		tbUpshiftAfterDownshift.Text = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay.ToGUIFormat()
 
 		'ChTCon.Checked = False				'set by CbGStype.SelectedIndexChanged
 		TbTCfile.Text = ""
@@ -207,6 +211,7 @@ Public Class GearboxForm
 		Text = "GBX Editor"
 		LbStatus.Text = ""
 
+
 		_changed = False
 		UpdatePic()
 	End Sub
@@ -239,11 +244,13 @@ Public Class GearboxForm
 
 		LvGears.Items.Clear()
 
-		LvGears.Items.Add(CreateListviewItem("Axle", axlegear.Ratio, GetRelativePath(axlegear.LossMap.Source, basePath),
-											"", ""))
+		LvGears.Items.Add(CreateListviewItem("Axle", axlegear.Ratio,
+											If(axlegear.LossMap Is Nothing, axlegear.Efficiency.ToGUIFormat(),
+												GetRelativePath(axlegear.LossMap.Source, basePath)), "", ""))
 
 		For Each gear As ITransmissionInputData In gearbox.Gears
-			LvGears.Items.Add(CreateListviewItem(gear.Gear.ToString("00"), gear.Ratio, gear.LossMap.Source,
+			LvGears.Items.Add(CreateListviewItem(gear.Gear.ToString("00"), gear.Ratio,
+												If(gear.LossMap Is Nothing, gear.Efficiency.ToGUIFormat(), gear.LossMap.Source),
 												If(gear.ShiftPolygon Is Nothing, "", GetRelativePath(gear.ShiftPolygon.Source, basePath)),
 												If(gear.MaxTorque Is Nothing, "", gear.MaxTorque.ToGUIFormat())))
 		Next
@@ -324,8 +331,8 @@ Public Class GearboxForm
 		gearbox.ModelName = TbName.Text
 		If Trim(gearbox.ModelName) = "" Then gearbox.ModelName = "Undefined"
 
-		gearbox.TracIntrSi = TbTracInt.Text.ToDouble()
-		gearbox.GbxInertia = TBI_getr.Text.ToDouble()
+		gearbox.TracIntrSi = TbTracInt.Text.ToDouble(0)
+		gearbox.GbxInertia = TBI_getr.Text.ToDouble(0)
 
 		For i = 0 To LvGears.Items.Count - 1
 			'GBX0.IsTCgear.Add(Me.LvGears.Items(i).SubItems(GearboxTbl.TorqueConverter).Text = "on" And i > 0)
@@ -339,25 +346,25 @@ Public Class GearboxForm
 			gearbox.MaxTorque.Add(LvGears.Items(i).SubItems(GearboxTbl.MaxTorque).Text)
 		Next
 
-		gearbox.TorqueResv = TbTqResv.Text.ToDouble()
+		gearbox.TorqueResv = TbTqResv.Text.ToDouble(0)
 		gearbox.SkipGears = ChSkipGears.Checked
-		gearbox.ShiftTime = TbShiftTime.Text.ToDouble()
-		gearbox.TorqueResvStart = TbTqResvStart.Text.ToDouble()
-		gearbox.StartSpeed = TbStartSpeed.Text.ToDouble()
-		gearbox.StartAcc = TbStartAcc.Text.ToDouble()
+		gearbox.ShiftTime = TbShiftTime.Text.ToDouble(0)
+		gearbox.TorqueResvStart = TbTqResvStart.Text.ToDouble(0)
+		gearbox.StartSpeed = TbStartSpeed.Text.ToDouble(0)
+		gearbox.StartAcc = TbStartAcc.Text.ToDouble(0)
 		gearbox.ShiftInside = ChShiftInside.Checked
 
 		gearbox.Type = CType(CbGStype.SelectedValue, GearboxType)
 
 		gearbox.TorqueConverterEnabled = gearbox.Type.AutomaticTransmission()
 		gearbox.TorqueConverterFile = TbTCfile.Text
-		gearbox.TorqueConverterReferenceRpm = TbTCrefrpm.Text.ToDouble()
-		gearbox.TorqueConverterInertia = TbTCinertia.Text.ToDouble()
+		gearbox.TorqueConverterReferenceRpm = TbTCrefrpm.Text.ToDouble(0)
+		gearbox.TorqueConverterInertia = TbTCinertia.Text.ToDouble(0)
 		gearbox.TorqueConverterShiftPolygonFile = TBTCShiftPolygon.Text
 
-		gearbox.DownshiftAfterUpshift = tbDownshiftAfterUpshift.Text.ToDouble()
-		gearbox.UpshiftAfterDownshift = tbUpshiftAfterDownshift.Text.ToDouble()
-		gearbox.UpshiftMinAcceleration = tbUpshiftMinAcceleration.Text.ToDouble()
+		gearbox.DownshiftAfterUpshift = tbDownshiftAfterUpshift.Text.ToDouble(0)
+		gearbox.UpshiftAfterDownshift = tbUpshiftAfterDownshift.Text.ToDouble(0)
+		gearbox.UpshiftMinAcceleration = tbUpshiftMinAcceleration.Text.ToDouble(0)
 
 		If Not gearbox.SaveFile Then
 			MsgBox("Cannot safe to " & file, MsgBoxStyle.Critical)
@@ -751,67 +758,69 @@ Public Class GearboxForm
 
 		'Dim vectoJob As VectoJob = New VectoJob() With {.FilePath = VectoJobForm.VECTOfile}
 		'Dim vectoOk As Boolean = vectoJob.ReadFile()
+		Dim jobFile As String = VectoJobForm.VectoFile
+		If Not jobFile Is Nothing AndAlso File.Exists(jobFile) Then
 
-		Dim inputData As IEngineeringInputDataProvider = TryCast(JSONInputDataFactory.ReadJsonJob(VectoJobForm.VECTOfile), 
-																IEngineeringInputDataProvider)
-		If (inputData Is Nothing) Then
-			Exit Sub
-		End If
-		Dim vehicle As IVehicleEngineeringInputData = inputData.VehicleInputData
-		'inputData = TryCast(JSONInputDataFactory.ReadComponentData(vectoJob.PathEng(False)), IEngineeringInputDataProvider)
-		Dim engine As IEngineEngineeringInputData = inputData.EngineInputData
-		Dim engineFld As EngineFullLoadCurve = EngineFullLoadCurve.Create(engine.FullLoadCurve)
-
-
-		s = New Series
-		s.Points.DataBindXY(engineFld.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
-							engineFld.FullLoadEntries.Select(Function(x) x.TorqueFullLoad.Value()).ToArray())
-		s.ChartType = SeriesChartType.FastLine
-		s.BorderWidth = 2
-		s.Color = Color.DarkBlue
-		s.Name = "Full load"
-		chart.Series.Add(s)
-
-		If VectoJobForm.Visible AndAlso engine.IdleSpeed > 0 Then
-			'If FLD0.Init(VectoJobForm.n_idle) Then
-
-			'Dim fullLoadCurve As FullLoadCurve = ConvertToFullLoadCurve(FLD0.LnU, FLD0.LTq)
-			Dim gears As IList(Of ITransmissionInputData) = ConvertToGears(LvGears.Items)
-			Dim shiftLines As ShiftPolygon = GetShiftLines(engine.IdleSpeed, engineFld, vehicle, gears, gear)
-			If (CType(CbGStype.SelectedValue, GearboxType).ManualTransmission() AndAlso Not IsNothing(shiftLines)) Then
-
-
-				s = New Series
-
-				's.Points.DataBindXY(Shiftpoly.gs_nUup, Shiftpoly.gs_TqUp)
-				s.Points.DataBindXY(
-					shiftLines.Upshift.Select(Function(pt) pt.AngularSpeed.AsRPM).
-										ToArray(),
-					shiftLines.Upshift.Select(Function(pt) pt.Torque.Value()).ToArray())
-				s.ChartType = SeriesChartType.FastLine
-				s.BorderWidth = 2
-				s.Color = Color.DarkRed
-				s.BorderDashStyle = ChartDashStyle.Dash
-				s.Name = "Upshift curve (generic)"
-				chart.Series.Add(s)
-
-				s = New Series
-				's.Points.DataBindXY(Shiftpoly.gs_nUdown, Shiftpoly.gs_TqDown)
-				s.Points.DataBindXY(
-					shiftLines.Downshift.Select(Function(pt) pt.AngularSpeed.AsRPM) _
-										.ToArray(),
-					shiftLines.Downshift.Select(Function(pt) pt.Torque.Value()).ToArray())
-				s.ChartType = SeriesChartType.FastLine
-				s.BorderWidth = 2
-				s.Color = Color.DarkRed
-				s.BorderDashStyle = ChartDashStyle.Dash
-				s.Name = "Downshift curve (generic)"
-				chart.Series.Add(s)
+			Dim inputData As IEngineeringInputDataProvider = TryCast(JSONInputDataFactory.ReadJsonJob(jobFile), 
+																	IEngineeringInputDataProvider)
+			If (inputData Is Nothing) Then
+				Exit Sub
 			End If
-			'End If
-		End If
+			Dim vehicle As IVehicleEngineeringInputData = inputData.VehicleInputData
+			'inputData = TryCast(JSONInputDataFactory.ReadComponentData(vectoJob.PathEng(False)), IEngineeringInputDataProvider)
+			Dim engine As IEngineEngineeringInputData = inputData.EngineInputData
+			Dim engineFld As EngineFullLoadCurve = EngineFullLoadCurve.Create(engine.FullLoadCurve)
 
 
+			s = New Series
+			s.Points.DataBindXY(engineFld.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
+								engineFld.FullLoadEntries.Select(Function(x) x.TorqueFullLoad.Value()).ToArray())
+			s.ChartType = SeriesChartType.FastLine
+			s.BorderWidth = 2
+			s.Color = Color.DarkBlue
+			s.Name = "Full load"
+			chart.Series.Add(s)
+
+			If VectoJobForm.Visible AndAlso engine.IdleSpeed > 0 Then
+				'If FLD0.Init(VectoJobForm.n_idle) Then
+
+				'Dim fullLoadCurve As FullLoadCurve = ConvertToFullLoadCurve(FLD0.LnU, FLD0.LTq)
+				Dim gears As IList(Of ITransmissionInputData) = ConvertToGears(LvGears.Items)
+				Dim shiftLines As ShiftPolygon = GetShiftLines(engine.IdleSpeed, engineFld, vehicle, gears, gear)
+				If (CType(CbGStype.SelectedValue, GearboxType).ManualTransmission() AndAlso Not IsNothing(shiftLines)) Then
+
+
+					s = New Series
+
+					's.Points.DataBindXY(Shiftpoly.gs_nUup, Shiftpoly.gs_TqUp)
+					s.Points.DataBindXY(
+						shiftLines.Upshift.Select(Function(pt) pt.AngularSpeed.AsRPM).
+											ToArray(),
+						shiftLines.Upshift.Select(Function(pt) pt.Torque.Value()).ToArray())
+					s.ChartType = SeriesChartType.FastLine
+					s.BorderWidth = 2
+					s.Color = Color.DarkRed
+					s.BorderDashStyle = ChartDashStyle.Dash
+					s.Name = "Upshift curve (generic)"
+					chart.Series.Add(s)
+
+					s = New Series
+					's.Points.DataBindXY(Shiftpoly.gs_nUdown, Shiftpoly.gs_TqDown)
+					s.Points.DataBindXY(
+						shiftLines.Downshift.Select(Function(pt) pt.AngularSpeed.AsRPM) _
+											.ToArray(),
+						shiftLines.Downshift.Select(Function(pt) pt.Torque.Value()).ToArray())
+					s.ChartType = SeriesChartType.FastLine
+					s.BorderWidth = 2
+					s.Color = Color.DarkRed
+					s.BorderDashStyle = ChartDashStyle.Dash
+					s.Name = "Downshift curve (generic)"
+					chart.Series.Add(s)
+				End If
+				'End If
+			End If
+		End If
+
 		a.Name = "main"
 
 		a.AxisX.Title = "engine speed [1/min]"
diff --git a/VECTO/GUI/GearboxGearDialog.vb b/VECTO/GUI/GearboxGearDialog.vb
index a021447be0..f7f89c398e 100644
--- a/VECTO/GUI/GearboxGearDialog.vb
+++ b/VECTO/GUI/GearboxGearDialog.vb
@@ -8,8 +8,16 @@
 '   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 '
 ' See the LICENSE.txt for the specific language governing permissions and limitations.
+Imports System.Collections.Generic
+Imports System.ComponentModel.DataAnnotations
+Imports System.IO
+Imports System.Linq
 Imports System.Windows.Forms
+Imports TUGraz.VectoCommon.Models
 Imports TUGraz.VectoCommon.Utils
+Imports TUGraz.VectoCore.InputData.Reader
+Imports TUGraz.VectoCore.InputData.Reader.ComponentData
+Imports TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 
 
 ''' <summary>
@@ -23,18 +31,10 @@ Public Class GearboxGearDialog
 
 	'Save and Close
 	Private Sub OK_Button_Click(sender As Object, e As EventArgs) Handles OK_Button.Click
-
-		If Not IsNumeric(TbRatio.Text) Then
-			MsgBox("Gear ratio is invalid!")
-			TbRatio.Focus()
-			TbRatio.SelectAll()
-			Exit Sub
-		End If
-
-		If IsNumeric(TbMapPath.Text) AndAlso (TbMapPath.Text.ToDouble() < 0 OrElse TbMapPath.Text.ToDouble() > 1) Then
-			MsgBox("Efficiency is invalid! Must be between 0 and 1.")
-			TbMapPath.Focus()
-			TbMapPath.SelectAll()
+		Dim results As IList(Of String) = ValidateGear()
+		If results.Any() Then
+			MsgBox("Invalid input:" + Environment.NewLine + String.Join(Environment.NewLine, results), MsgBoxStyle.OkOnly,
+					"Failed to save gear")
 			Exit Sub
 		End If
 
@@ -44,6 +44,45 @@ Public Class GearboxGearDialog
 		Close()
 	End Sub
 
+	Private Function ValidateGear() As IList(Of String)
+		If String.IsNullOrWhiteSpace(TbMapPath.Text) Then _
+			Return New List(Of String)() From {"Loss-Map or Efficiency required"}
+		Try
+			Dim lossMapFile As String =
+					If(Not String.IsNullOrWhiteSpace(GbxPath), Path.Combine(GbxPath, TbMapPath.Text), TbMapPath.Text)
+			Dim lossmap As TransmissionLossMap
+			If File.Exists(lossMapFile) Then
+				lossmap = TransmissionLossMapReader.ReadFromFile(lossMapFile, TbRatio.Text.ToDouble(0), "gear " + TbGear.Text)
+			Else
+				lossmap = TransmissionLossMapReader.Create(TbMapPath.Text.ToDouble(0), TbRatio.Text.ToDouble(0),
+															"gear " + TbGear.Text)
+			End If
+			Dim shiftPolygon As ShiftPolygon = Nothing
+			If (Not String.IsNullOrWhiteSpace(TbShiftPolyFile.Text)) Then
+				Dim shiftPolygonFile As String =
+						If(Not String.IsNullOrWhiteSpace(GbxPath), Path.Combine(GbxPath, TbShiftPolyFile.Text), TbShiftPolyFile.Text)
+				shiftPolygon = ShiftPolygonReader.ReadFromFile(shiftPolygonFile)
+			End If
+			Dim gearData As GearData = New GearData() With {
+					.Ratio = TbRatio.Text.ToDouble(0),
+					.LossMap = lossmap,
+					.ShiftPolygon = shiftPolygon,
+					.MaxTorque =
+					If(String.IsNullOrWhiteSpace(TbMaxTorque.Text), Nothing, TbMaxTorque.Text.ToDouble().SI(Of NewtonMeter))
+					}
+			Dim results As IList(Of ValidationResult) =
+					gearData.Validate(If(Cfg.DeclMode, ExecutionMode.Declaration, ExecutionMode.Engineering))
+
+			If (results.Any()) Then
+				Return results.Select(Function(r) r.ErrorMessage + String.Join(", ", r.MemberNames.Distinct())).ToList()
+			End If
+		Catch ex As Exception
+			Return New List(Of String)() From {ex.Message}
+		End Try
+
+		Return New List(Of String)()
+	End Function
+
 	'Cancel
 	Private Sub Cancel_Button_Click(sender As Object, e As EventArgs) Handles Cancel_Button.Click
 		NextGear = False
diff --git a/VECTO/GUI/VectoJobForm.vb b/VECTO/GUI/VectoJobForm.vb
index 938393ee52..80bf50e3fb 100644
--- a/VECTO/GUI/VectoJobForm.vb
+++ b/VECTO/GUI/VectoJobForm.vb
@@ -353,7 +353,12 @@ Public Class VectoJobForm
 				Return False
 			End If
 		End If
-		Return VECTOsave(VectoFile)
+		Try
+			Return VECTOsave(VectoFile)
+		Catch ex As Exception
+			MsgBox("Error when saving file" + Environment.NewLine + ex.Message)
+			Return False
+		End Try
 	End Function
 
 	'Open file
@@ -524,36 +529,36 @@ Public Class VectoJobForm
 		End If
 
 
-		Dim vec0 As VectoJob = New VectoJob
-		vec0.FilePath = file
+		Dim vectoJob As VectoJob = New VectoJob
+		vectoJob.FilePath = file
 
 		'Files ------------------------------------------------- -----------------
 
-		vec0.PathVeh = TbVEH.Text
-		vec0.PathEng = TbENG.Text
+		vectoJob.PathVeh = TbVEH.Text
+		vectoJob.PathEng = TbENG.Text
 
 		For Each lv0 As ListViewItem In LvCycles.Items
 			Dim sb As SubPath = New SubPath
 			sb.Init(GetPath(file), lv0.Text)
-			vec0.CycleFiles.Add(sb)
+			vectoJob.CycleFiles.Add(sb)
 		Next
 
-		vec0.PathGbx = TbGBX.Text
+		vectoJob.PathGbx = TbGBX.Text
 
 
 		'Start/Stop
-		vec0.StartStop = ChBStartStop.Checked
-		vec0.StartStopMaxSpeed = TbSSspeed.Text.ToDouble()
-		vec0.StartStopTime = TbSStime.Text.ToDouble()
-		vec0.StartStopDelay = TbSSdelay.Text.ToDouble()
+		vectoJob.StartStop = ChBStartStop.Checked
+		vectoJob.StartStopMaxSpeed = TbSSspeed.Text.ToDouble()
+		vectoJob.StartStopTime = TbSStime.Text.ToDouble()
+		vectoJob.StartStopDelay = TbSSdelay.Text.ToDouble()
 
 		'a_DesMax
-		vec0.DesMaxFile = TbDesMaxFile.Text
+		vectoJob.DesMaxFile = TbDesMaxFile.Text
 
 		'AA-TB
-		vec0.AuxiliaryAssembly = DirectCast(cboAdvancedAuxiliaries.SelectedItem, AdvancedAuxiliary).AssemblyName
-		vec0.AuxiliaryVersion = DirectCast(cboAdvancedAuxiliaries.SelectedItem, AdvancedAuxiliary).AuxiliaryVersion
-		vec0.AdvancedAuxiliaryFilePath = txtAdvancedAuxiliaryFile.Text
+		vectoJob.AuxiliaryAssembly = DirectCast(cboAdvancedAuxiliaries.SelectedItem, AdvancedAuxiliary).AssemblyName
+		vectoJob.AuxiliaryVersion = DirectCast(cboAdvancedAuxiliaries.SelectedItem, AdvancedAuxiliary).AuxiliaryVersion
+		vectoJob.AdvancedAuxiliaryFilePath = txtAdvancedAuxiliaryFile.Text
 
 		For Each lv0 As ListViewItem In LvAux.Items
 			Dim auxEntry As VectoJob.AuxEntry = New VectoJob.AuxEntry
@@ -566,29 +571,29 @@ Public Class VectoJobForm
 			End If
 
 			auxEntry.Type = lv0.SubItems(1).Text
-			vec0.AuxPaths.Add(lv0.SubItems(0).Text, auxEntry)
+			vectoJob.AuxPaths.Add(lv0.SubItems(0).Text, auxEntry)
 		Next
 
-		vec0.EngineOnly = CbEngOnly.Checked
+		vectoJob.EngineOnly = CbEngOnly.Checked
 
-		vec0.EcoRollOn = RdEcoRoll.Checked
-		vec0.OverSpeedOn = RdOverspeed.Checked
-		vec0.OverSpeed = TbOverspeed.Text.ToDouble(0)
-		vec0.UnderSpeed = TbUnderSpeed.Text.ToDouble(0)
-		vec0.VMin = TbVmin.Text.ToDouble(0)
-		vec0.LookAheadOn = CbLookAhead.Checked
+		vectoJob.EcoRollOn = RdEcoRoll.Checked
+		vectoJob.OverSpeedOn = RdOverspeed.Checked
+		vectoJob.OverSpeed = TbOverspeed.Text.ToDouble(0)
+		vectoJob.UnderSpeed = TbUnderSpeed.Text.ToDouble(0)
+		vectoJob.VMin = TbVmin.Text.ToDouble(0)
+		vectoJob.LookAheadOn = CbLookAhead.Checked
 		'vec0.ALookahead = CSng(fTextboxToNumString(TbAlookahead.Text))
 		'vec0.VMinLa = CSng(fTextboxToNumString(TbVminLA.Text))
-		vec0.LookAheadMinSpeed = tbLacMinSpeed.Text.ToDouble(0)
-		vec0.LacPreviewFactor = tbLacPreviewFactor.Text.ToDouble(0)
-		vec0.LacDfOffset = tbDfCoastingOffset.Text.ToDouble(0)
-		vec0.LacDfScale = tbDfCoastingScale.Text.ToDouble(0)
-		vec0.LacDfTargetSpeedFile = tbLacDfTargetSpeedFile.Text
-		vec0.LacDfVelocityDropFile = tbLacDfVelocityDropFile.Text
+		vectoJob.LookAheadMinSpeed = tbLacMinSpeed.Text.ToDouble(0)
+		vectoJob.LacPreviewFactor = tbLacPreviewFactor.Text.ToDouble(0)
+		vectoJob.LacDfOffset = tbDfCoastingOffset.Text.ToDouble(0)
+		vectoJob.LacDfScale = tbDfCoastingScale.Text.ToDouble(0)
+		vectoJob.LacDfTargetSpeedFile = tbLacDfTargetSpeedFile.Text
+		vectoJob.LacDfVelocityDropFile = tbLacDfVelocityDropFile.Text
 		'------------------------------------------------------------
 
 		'SAVE
-		If Not vec0.SaveFile Then
+		If Not vectoJob.SaveFile Then
 			MsgBox("Cannot safe to " & file, MsgBoxStyle.Critical)
 			Return False
 		End If
@@ -620,8 +625,9 @@ Public Class VectoJobForm
 		TbDesMaxFile.Text = ""
 
 		'Start/Stop
-		TbSSspeed.Text = "5"
-		TbSStime.Text = "5"
+		TbSSspeed.Text = DeclarationData.Driver.StartStop.MaxSpeed.AsKmph().ToGUIFormat()
+		TbSStime.Text = DeclarationData.Driver.StartStop.MinTime.ToGUIFormat()
+		TbSSdelay.Text = DeclarationData.Driver.StartStop.Delay.ToGUIFormat()
 		ChBStartStop.Checked = False
 
 		LvAux.Items.Clear()
@@ -631,13 +637,15 @@ Public Class VectoJobForm
 		RdOff.Checked = True
 		CbLookAhead.Checked = True
 		'TbAlookahead.Text = "-0.5"
-		TbOverspeed.Text = ""
-		TbUnderSpeed.Text = ""
-		TbVmin.Text = ""
+		TbOverspeed.Text = DeclarationData.Driver.OverSpeedEcoRoll.OverSpeed.AsKmph().ToGUIFormat()
+		TbUnderSpeed.Text = DeclarationData.Driver.OverSpeedEcoRoll.UnderSpeed.AsKmph().ToGUIFormat()
+		TbVmin.Text = DeclarationData.Driver.OverSpeedEcoRoll.MinSpeed.AsKmph().ToGUIFormat()
+
 		'TbVminLA.Text = "50"
-		tbLacPreviewFactor.Text = "10"
-		tbDfCoastingOffset.Text = "2.5"
-		tbDfCoastingScale.Text = "1.5"
+		tbLacMinSpeed.Text = DeclarationData.Driver.LookAhead.MinimumSpeed.AsKmph().ToGUIFormat()
+		tbLacPreviewFactor.Text = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor.ToGUIFormat()
+		tbDfCoastingOffset.Text = DeclarationData.Driver.LookAhead.DecisionFactorCoastingOffset.ToGUIFormat()
+		tbDfCoastingScale.Text = DeclarationData.Driver.LookAhead.DecisionFactorCoastingScaling.ToGUIFormat()
 		tbLacDfTargetSpeedFile.Text = ""
 		tbLacDfVelocityDropFile.Text = ""
 
@@ -1000,10 +1008,8 @@ lbDlog:
 		Dim i As Integer
 		Dim pmax As Double
 
-		Dim HDVclass As String
-
 		Dim s As Series
-		Dim a As ChartArea
+		Dim a As ChartArea = New ChartArea()
 		Dim img As Bitmap
 
 		Dim engOk As Boolean = False
@@ -1017,224 +1023,246 @@ lbDlog:
 		PicVehicle.Image = Nothing
 		PicBox.Image = Nothing
 
-		Dim inputData As IEngineeringInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(VectoFile), 
-																IEngineeringInputDataProvider)
-		Dim vehicle As IVehicleEngineeringInputData = inputData.VehicleInputData
-
-		If Not vehicle Is Nothing Then
-			Dim maxMass As Kilogram = vehicle.GrossVehicleMassRating					'CSng(fTextboxToNumString(TbMassMass.Text))
-
-			Dim s0 As Segment = Nothing
-			Try
-				s0 = DeclarationData.Segments.Lookup(vehicle.VehicleCategory, vehicle.AxleConfiguration, maxMass, 0.SI(Of Kilogram),
-													True)
-			Catch
-			End Try
-			If Not s0 Is Nothing Then
-				HDVclass = s0.VehicleClass.GetClassNumber()
-
-				If Cfg.DeclMode Then
-					LvCycles.Items.Clear()
-					Dim m0 As Mission
-					For Each m0 In s0.Missions
-						LvCycles.Items.Add(m0.MissionType.ToString())
-					Next
-				End If
-
-			Else
-				HDVclass = "-"
-			End If
-
-			PicVehicle.Image = ConvPicPath(If(s0 Is Nothing, -1, HDVclass.ToInt()), False) _
-			'Image.FromFile(cDeclaration.ConvPicPath(HDVclass, False))
+		UpdateVehiclePic()
 
-			TbHVCclass.Text = "HDV Class " & HDVclass
-			TbVehCat.Text = vehicle.VehicleCategory.GetCategoryName()	'ConvVehCat(VEH0.VehCat, True)
-			TbMass.Text = (vehicle.GrossVehicleMassRating.Value() / 1000) & " t"
-			TbAxleConf.Text = vehicle.AxleConfiguration.GetName()	'ConvAxleConf(VEH0.AxleConf)
+		Dim chart As Chart = Nothing
+		UpdateEnginePic(chart)
 
-		End If
 
+		UpdateGearboxPic(chart)
 
-		Dim okCount As Integer = 0
+		If chart Is Nothing Then Return
 
-		Dim engine As IEngineEngineeringInputData = inputData.EngineInputData
-		'engine.FilePath = fFileRepl(TbENG.Text, GetPath(VECTOfile))
+		a.Name = "main"
 
-		'Create plot
-		Dim chart As Chart = New Chart
-		chart.Width = PicBox.Width
-		chart.Height = PicBox.Height
+		a.AxisX.Title = "engine speed [1/min]"
+		a.AxisX.TitleFont = New Font("Helvetica", 10)
+		a.AxisX.LabelStyle.Font = New Font("Helvetica", 8)
+		a.AxisX.LabelAutoFitStyle = LabelAutoFitStyles.None
+		a.AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Dot
 
-		a = New ChartArea
+		a.AxisY.Title = "engine torque [Nm]"
+		a.AxisY.TitleFont = New Font("Helvetica", 10)
+		a.AxisY.LabelStyle.Font = New Font("Helvetica", 8)
+		a.AxisY.LabelAutoFitStyle = LabelAutoFitStyles.None
+		a.AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Dot
 
-		'Dim FLD0 As EngineFullLoadCurve = New EngineFullLoadCurve
+		a.AxisX.Minimum = 300
+		a.BorderDashStyle = ChartDashStyle.Solid
+		a.BorderWidth = 1
 
-		If Not engine Is Nothing Then
+		a.BackColor = Color.GhostWhite
 
-			engine.IdleSpeed.Value()
+		chart.ChartAreas.Add(a)
+		chart.Update()
 
-			Dim fullLoadCurve As FullLoadCurve = EngineFullLoadCurve.Create(engine.FullLoadCurve)
+		img = New Bitmap(chart.Width, chart.Height, PixelFormat.Format32bppArgb)
+		chart.DrawToBitmap(img, New Rectangle(0, 0, PicBox.Width, PicBox.Height))
 
-			s = New Series
-			s.Points.DataBindXY(fullLoadCurve.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
-								fullLoadCurve.FullLoadEntries.Select(Function(x) x.TorqueFullLoad.Value()).ToArray())
-			s.ChartType = SeriesChartType.FastLine
-			s.BorderWidth = 2
-			s.Color = Color.DarkBlue
-			s.Name = "Full load"
-			chart.Series.Add(s)
+		PicBox.Image = img
+	End Sub
 
-			s = New Series
-			s.Points.DataBindXY(fullLoadCurve.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
-								fullLoadCurve.FullLoadEntries.Select(Function(x) x.TorqueDrag.Value()).ToArray())
-			s.ChartType = SeriesChartType.FastLine
-			s.BorderWidth = 2
-			s.Color = Color.Blue
-			s.Name = "Motoring"
-			chart.Series.Add(s)
+	Private Sub UpdateGearboxPic(ByRef chartArea As Chart)
+		Dim s As Series
+		Dim i As Integer
 
-			okCount += 1
+		Dim gearbox As IGearboxEngineeringInputData = Nothing
+		Dim gearboxFile As String =
+				If(Not String.IsNullOrWhiteSpace(VectoFile), Path.Combine(Path.GetDirectoryName(VectoFile), TbGBX.Text), TbGBX.Text)
+		If File.Exists(gearboxFile) Then
+			Try
+				Dim inputData As IEngineeringInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(gearboxFile), 
+																		IEngineeringInputDataProvider)
+				gearbox = inputData.GearboxInputData
+			Catch
+			End Try
+		End If
 
-			pmax = fullLoadCurve.MaxPower.Value() / 1000 'FLD0.Pfull(FLD0.EngineRatedSpeed)
+		If gearbox Is Nothing Then Return
 
+		TbGbxTxt.Text = gearbox.Gears.Count & "-Speed " & gearbox.Type.ShortName() & "  " & gearbox.ModelName
 
-			TbEngTxt.Text = (engine.Displacement.Value() * 1000).ToString("0.0") & " l " & pmax.ToString("#") & " kW  " &
-							engine.ModelName
+		If Cfg.DeclMode Then
+			For i = 1 To gearbox.Gears.Count
+				'If FLD0.Init(ENG0.Nidle) Then '' use engine from below...
+
+				'Dim engine As CombustionEngineData = ConvertToEngineData(FLD0, F_VECTO.n_idle)
+				'Dim shiftLines As ShiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon(Gear - 1,
+				'																			engine.FullLoadCurve, gears,
+				'																			engine,
+				'																			Double.Parse(LvGears.Items(0).SubItems(F_GBX.GearboxTbl.Ratio).Text,
+				'																						CultureInfo.InvariantCulture),
+				'																			(.rdyn / 1000.0).SI(Of Meter))
+
+				's = New Series
+				's.Points.DataBindXY(shiftLines.Upshift.Select(Function(pt) pt.AngularSpeed.Value() / Constants.RPMToRad).ToList(),
+				'					shiftLines.Upshift.Select(Function(pt) pt.Torque.Value()).ToList())
+				's.ChartType = SeriesChartType.FastLine
+				's.BorderWidth = 2
+				's.Color = Color.DarkRed
+				's.Name = "Upshift curve (" & i & ")"
+				'MyChart.Series.Add(s)
+
+				's = New Series
+				's.Points.DataBindXY(
+				'	shiftLines.Downshift.Select(Function(pt) pt.AngularSpeed.Value() / Constants.RPMToRad).ToList(),
+				'	shiftLines.Downshift.Select(Function(pt) pt.Torque.Value()).ToList())
+				's.ChartType = SeriesChartType.FastLine
+				's.BorderWidth = 2
+				's.Color = Color.DarkRed
+				's.Name = "Downshift curve (" & i & ")"
+				'MyChart.Series.Add(s)
+				'End If
+
+				'	OkCount += 1
+
+				'	pmax = FLD0.Pfull(FLD0.EngineRatedSpeed)
+
+				'End If
+			Next
+		Else
+			For Each gear As ITransmissionInputData In gearbox.Gears
+				If gear.ShiftPolygon Is Nothing OrElse gear.ShiftPolygon.Rows.Count = 0 Then Continue For
+				Dim shiftPolygon As ShiftPolygon = ShiftPolygonReader.Create(gear.ShiftPolygon)
+				s = New Series
+				s.Points.DataBindXY(shiftPolygon.Upshift.Select(Function(x) x.AngularSpeed),
+									shiftPolygon.Upshift.Select(Function(x) x.Torque))
+				s.ChartType = SeriesChartType.FastLine
+				s.BorderWidth = 2
+				s.Color = Color.DarkRed
+				s.Name = "Upshift curve"
+				' MyChart.Series.Add(s) 'MQ 2016-06-20: do not plot shift lines in engine dialog
+
+				s = New Series
+				s.Points.DataBindXY(shiftPolygon.Downshift.Select(Function(x) x.AngularSpeed),
+									shiftPolygon.Downshift.Select(Function(x) x.Torque))
+				s.ChartType = SeriesChartType.FastLine
+				s.BorderWidth = 2
+				s.Color = Color.DarkRed
+				s.Name = "Downshift curve"
+				'MyChart.Series.Add(s) 'MQ 2016-06-20:do not plot shift lines in engine dialog
+			Next
+		End If
+	End Sub
 
-			Dim fuelConsumptionMap As FuelConsumptionMap = FuelConsumptionMapReader.Create(engine.FuelConsumptionMap)
+	Private Sub UpdateEnginePic(ByRef chart As Chart)
+		Dim s As Series
+		Dim pmax As Double
 
-			s = New Series
-			s.Points.DataBindXY(fuelConsumptionMap.Entries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
-								fuelConsumptionMap.Entries.Select(Function(x) x.Torque.Value()).ToArray())
-			s.ChartType = SeriesChartType.Point
-			s.MarkerSize = 3
-			s.Color = Color.Red
-			s.Name = "Map"
-			chart.Series.Add(s)
+		Dim engine As IEngineEngineeringInputData = Nothing
+		Dim engineFile As String =
+				If(Not String.IsNullOrWhiteSpace(VectoFile), Path.Combine(Path.GetDirectoryName(VectoFile), TbENG.Text), TbENG.Text)
+		If File.Exists(engineFile) Then
+			Try
+				Dim inputData As IEngineeringInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(engineFile), 
+																		IEngineeringInputDataProvider)
+				engine = inputData.EngineInputData
+			Catch
+				Return
+			End Try
+		End If
 
-			okCount += 1
+		'engine.FilePath = fFileRepl(TbENG.Text, GetPath(VECTOfile))
 
+		'Create plot
+		chart = New Chart
+		chart.Width = PicBox.Width
+		chart.Height = PicBox.Height
 
-		End If
 
-		Dim gearbox As IGearboxEngineeringInputData = inputData.GearboxInputData
+		'Dim FLD0 As EngineFullLoadCurve = New EngineFullLoadCurve
 
-		If Not gearbox Is Nothing Then
+		If engine Is Nothing Then Return
 
-			TbGbxTxt.Text = gearbox.Gears.Count & "-Speed " & gearbox.Type.ShortName() & "  " & gearbox.ModelName
 
-			If Cfg.DeclMode Then
+		engine.IdleSpeed.Value()
 
-				If engOk Then
+		Dim fullLoadCurve As FullLoadCurve = EngineFullLoadCurve.Create(engine.FullLoadCurve)
 
-					For i = 1 To gearbox.Gears.Count
+		s = New Series
+		s.Points.DataBindXY(fullLoadCurve.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
+							fullLoadCurve.FullLoadEntries.Select(Function(x) x.TorqueFullLoad.Value()).ToArray())
+		s.ChartType = SeriesChartType.FastLine
+		s.BorderWidth = 2
+		s.Color = Color.DarkBlue
+		s.Name = "Full load"
+		chart.Series.Add(s)
 
+		s = New Series
+		s.Points.DataBindXY(fullLoadCurve.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
+							fullLoadCurve.FullLoadEntries.Select(Function(x) x.TorqueDrag.Value()).ToArray())
+		s.ChartType = SeriesChartType.FastLine
+		s.BorderWidth = 2
+		s.Color = Color.Blue
+		s.Name = "Motoring"
+		chart.Series.Add(s)
 
-						'If FLD0.Init(ENG0.Nidle) Then '' use engine from below...
+		pmax = fullLoadCurve.MaxPower.Value() / 1000 'FLD0.Pfull(FLD0.EngineRatedSpeed)
 
-						'Dim engine As CombustionEngineData = ConvertToEngineData(FLD0, F_VECTO.n_idle)
-						'Dim shiftLines As ShiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon(Gear - 1,
-						'																			engine.FullLoadCurve, gears,
-						'																			engine,
-						'																			Double.Parse(LvGears.Items(0).SubItems(F_GBX.GearboxTbl.Ratio).Text,
-						'																						CultureInfo.InvariantCulture),
-						'																			(.rdyn / 1000.0).SI(Of Meter))
 
-						's = New Series
-						's.Points.DataBindXY(shiftLines.Upshift.Select(Function(pt) pt.AngularSpeed.Value() / Constants.RPMToRad).ToList(),
-						'					shiftLines.Upshift.Select(Function(pt) pt.Torque.Value()).ToList())
-						's.ChartType = SeriesChartType.FastLine
-						's.BorderWidth = 2
-						's.Color = Color.DarkRed
-						's.Name = "Upshift curve (" & i & ")"
-						'MyChart.Series.Add(s)
+		TbEngTxt.Text = (engine.Displacement.Value() * 1000).ToString("0.0") & " l " & pmax.ToString("#") & " kW  " &
+						engine.ModelName
 
-						's = New Series
-						's.Points.DataBindXY(
-						'	shiftLines.Downshift.Select(Function(pt) pt.AngularSpeed.Value() / Constants.RPMToRad).ToList(),
-						'	shiftLines.Downshift.Select(Function(pt) pt.Torque.Value()).ToList())
-						's.ChartType = SeriesChartType.FastLine
-						's.BorderWidth = 2
-						's.Color = Color.DarkRed
-						's.Name = "Downshift curve (" & i & ")"
-						'MyChart.Series.Add(s)
-						'End If
+		Dim fuelConsumptionMap As FuelConsumptionMap = FuelConsumptionMapReader.Create(engine.FuelConsumptionMap)
 
+		s = New Series
+		s.Points.DataBindXY(fuelConsumptionMap.Entries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(),
+							fuelConsumptionMap.Entries.Select(Function(x) x.Torque.Value()).ToArray())
+		s.ChartType = SeriesChartType.Point
+		s.MarkerSize = 3
+		s.Color = Color.Red
+		s.Name = "Map"
+		chart.Series.Add(s)
+	End Sub
 
-						'	OkCount += 1
+	Private Sub UpdateVehiclePic()
+		Dim HDVclass As String
 
-						'	pmax = FLD0.Pfull(FLD0.EngineRatedSpeed)
+		Dim vehicle As IVehicleEngineeringInputData = Nothing
 
-						'End If
+		Dim vehicleFile As String =
+				If(Not String.IsNullOrWhiteSpace(VectoFile), Path.Combine(Path.GetDirectoryName(VectoFile), TbVEH.Text), TbVEH.Text)
+		If File.Exists(vehicleFile) Then
+			Try
+				Dim inputData As IEngineeringInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(vehicleFile), 
+																		IEngineeringInputDataProvider)
+				vehicle = inputData.VehicleInputData
+			Catch
+			End Try
+		End If
 
-					Next
+		If vehicle Is Nothing Then Return
 
-				End If
+		Dim maxMass As Kilogram = vehicle.GrossVehicleMassRating					'CSng(fTextboxToNumString(TbMassMass.Text))
 
-			Else
+		Dim s0 As Segment = Nothing
+		Try
+			s0 = DeclarationData.Segments.Lookup(vehicle.VehicleCategory, vehicle.AxleConfiguration, maxMass, 0.SI(Of Kilogram),
+												True)
+		Catch
+		End Try
+		If s0 Is Nothing Then
+			HDVclass = "-"
+		Else
+			HDVclass = s0.VehicleClass.GetClassNumber()
 
-				For Each gear As ITransmissionInputData In gearbox.Gears
-					If gear.ShiftPolygon Is Nothing OrElse gear.ShiftPolygon.Rows.Count = 0 Then Continue For
-					Dim shiftPolygon As ShiftPolygon = ShiftPolygonReader.Create(gear.ShiftPolygon)
-					s = New Series
-					s.Points.DataBindXY(shiftPolygon.Upshift.Select(Function(x) x.AngularSpeed),
-										shiftPolygon.Upshift.Select(Function(x) x.Torque))
-					s.ChartType = SeriesChartType.FastLine
-					s.BorderWidth = 2
-					s.Color = Color.DarkRed
-					s.Name = "Upshift curve"
-					' MyChart.Series.Add(s) 'MQ 2016-06-20: do not plot shift lines in engine dialog
-
-					s = New Series
-					s.Points.DataBindXY(shiftPolygon.Downshift.Select(Function(x) x.AngularSpeed),
-										shiftPolygon.Downshift.Select(Function(x) x.Torque))
-					s.ChartType = SeriesChartType.FastLine
-					s.BorderWidth = 2
-					s.Color = Color.DarkRed
-					s.Name = "Downshift curve"
-					'MyChart.Series.Add(s) 'MQ 2016-06-20:do not plot shift lines in engine dialog
-
-					okCount += 1
+			If Cfg.DeclMode Then
+				LvCycles.Items.Clear()
+				Dim m0 As Mission
+				For Each m0 In s0.Missions
+					LvCycles.Items.Add(m0.MissionType.ToString())
 				Next
-
 			End If
 
 		End If
 
-		If okCount > 0 Then
-
-			a.Name = "main"
-
-			a.AxisX.Title = "engine speed [1/min]"
-			a.AxisX.TitleFont = New Font("Helvetica", 10)
-			a.AxisX.LabelStyle.Font = New Font("Helvetica", 8)
-			a.AxisX.LabelAutoFitStyle = LabelAutoFitStyles.None
-			a.AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Dot
+		PicVehicle.Image = ConvPicPath(If(s0 Is Nothing, -1, HDVclass.ToInt()), False) _
+		'Image.FromFile(cDeclaration.ConvPicPath(HDVclass, False))
 
-			a.AxisY.Title = "engine torque [Nm]"
-			a.AxisY.TitleFont = New Font("Helvetica", 10)
-			a.AxisY.LabelStyle.Font = New Font("Helvetica", 8)
-			a.AxisY.LabelAutoFitStyle = LabelAutoFitStyles.None
-			a.AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Dot
-
-			a.AxisX.Minimum = 300
-			a.BorderDashStyle = ChartDashStyle.Solid
-			a.BorderWidth = 1
-
-			a.BackColor = Color.GhostWhite
-
-			chart.ChartAreas.Add(a)
-
-			chart.Update()
-
-			img = New Bitmap(chart.Width, chart.Height, PixelFormat.Format32bppArgb)
-			chart.DrawToBitmap(img, New Rectangle(0, 0, PicBox.Width, PicBox.Height))
-
-			PicBox.Image = img
-
-
-		End If
+		TbHVCclass.Text = "HDV Class " & HDVclass
+		TbVehCat.Text = vehicle.VehicleCategory.GetCategoryName()	'ConvVehCat(VEH0.VehCat, True)
+		TbMass.Text = (vehicle.GrossVehicleMassRating.Value() / 1000) & " t"
+		TbAxleConf.Text = vehicle.AxleConfiguration.GetName()	'ConvAxleConf(VEH0.AxleConf)
 	End Sub
 
 
diff --git a/VECTO/GUI/VehicleAxleDialog.vb b/VECTO/GUI/VehicleAxleDialog.vb
index 43a6468b52..9763d04bcc 100644
--- a/VECTO/GUI/VehicleAxleDialog.vb
+++ b/VECTO/GUI/VehicleAxleDialog.vb
@@ -12,6 +12,12 @@ Option Infer On
 Option Strict On
 Option Explicit On
 
+Imports System.Collections.Generic
+Imports System.ComponentModel.DataAnnotations
+Imports System.Linq
+Imports TUGraz.VectoCommon.Models
+Imports TUGraz.VectoCommon.Utils
+Imports TUGraz.VectoCore.InputData.Impl
 Imports TUGraz.VectoCore.Models.Declaration
 
 
@@ -43,20 +49,23 @@ Public Class VehicleAxleDialog
 	'Save and close
 	Private Sub OK_Button_Click(sender As Object, e As EventArgs) Handles OK_Button.Click
 
-		If Not Cfg.DeclMode Then
-			If Not IsNumeric(TbAxleShare.Text) OrElse Trim(TbAxleShare.Text) = "" Then
-				MsgBox("Weight input is not valid!")
-				Exit Sub
-			End If
-		End If
+		Dim axleData As Axle = New Axle With {
+				.AxleWeightShare = TbAxleShare.Text.ToDouble(0),
+				.RollResistanceCoefficient = TbRRC.Text.ToDouble(0),
+				.TyreTestLoad = TbFzISO.Text.ToDouble(0).SI(Of Newton)(),
+				.TwinTyres = CbTwinT.Checked,
+				.WheelsDimension = CbWheels.SelectedItem.ToString(),
+				.Inertia = TbI_wheels.Text.ToDouble(0).SI(Of KilogramSquareMeter)()
+				}
 
-		If Not IsNumeric(TbRRC.Text) OrElse Trim(TbRRC.Text) = "" Then
-			MsgBox("RRC input is not valid!")
-			Exit Sub
-		End If
+		Dim results As IList(Of ValidationResult) =
+				axleData.Validate(If(Cfg.DeclMode, ExecutionMode.Declaration, ExecutionMode.Engineering))
 
-		If Not IsNumeric(TbFzISO.Text) OrElse Trim(TbFzISO.Text) = "" Then
-			MsgBox("Fz ISO input is not valid!")
+		If results.Any() Then
+			Dim messages As IEnumerable(Of String) =
+					results.Select(Function(r) r.ErrorMessage + String.Join(", ", r.MemberNames.Distinct()))
+			MsgBox("Invalid input:" + Environment.NewLine + String.Join(Environment.NewLine, messages), MsgBoxStyle.OkOnly,
+					"Failed to save axle gear")
 			Exit Sub
 		End If
 
diff --git a/VECTO/GUI/VehicleForm.vb b/VECTO/GUI/VehicleForm.vb
index d4cbe41866..d17350647b 100644
--- a/VECTO/GUI/VehicleForm.vb
+++ b/VECTO/GUI/VehicleForm.vb
@@ -232,7 +232,7 @@ Public Class VehicleForm
 		If Not VectoJobForm.Visible Then
 			JobDir = ""
 			VectoJobForm.Show()
-			VectoJobForm.VECTOnew()
+			VectoJobForm.VectoNew()
 		Else
 			VectoJobForm.WindowState = FormWindowState.Normal
 		End If
@@ -347,7 +347,7 @@ Public Class VehicleForm
 		TbMass.Text = vehicle.CurbWeightChassis.ToGUIFormat()
 		TbMassExtra.Text = vehicle.CurbWeightExtra.ToGUIFormat()
 		TbLoad.Text = vehicle.Loading.ToGUIFormat()
-		TBrdyn.Text = vehicle.DynamicTyreRadius.ToGUIFormat()
+		TBrdyn.Text = (vehicle.DynamicTyreRadius.Value() * 1000).ToGUIFormat()
 
 		CbCdMode.SelectedValue = vehicle.CrossWindCorrectionMode
 		TbCdFile.Text =
@@ -430,21 +430,21 @@ Public Class VehicleForm
 		Dim veh As Vehicle = New Vehicle
 		veh.FilePath = file
 
-		veh.Mass = TbMass.Text.ToDouble()
+		veh.Mass = TbMass.Text.ToDouble(0)
 		veh.MassExtra = TbMassExtra.Text.ToDouble(0)
 		veh.Loading = TbLoad.Text.ToDouble(0)
 
-		veh.CdA0 = TBcdA.Text.ToDouble()
+		veh.CdA0 = TBcdA.Text.ToDouble(0)
 
 		veh.DynamicTyreRadius = TBrdyn.Text.ToDouble(0)
 		veh.CrossWindCorrectionMode = CType(CbCdMode.SelectedValue, CrossWindCorrectionMode)
 		veh.CrossWindCorrectionFile.Init(GetPath(file), TbCdFile.Text)
 		veh.RetarderType = CType(CbRtType.SelectedValue, RetarderType)
-		veh.RetarderRatio = TbRtRatio.Text.ToDouble()
+		veh.RetarderRatio = TbRtRatio.Text.ToDouble(0)
 		veh.RetarderLossMapFile.Init(GetPath(file), TbRtPath.Text)
 
 		veh.AngularGearType = CType(cbAngularGearType.SelectedValue, AngularGearType)
-		veh.AngularGearRatio = tbAngularGearRatio.Text.ToDouble()
+		veh.AngularGearRatio = tbAngularGearRatio.Text.ToDouble(0)
 		veh.AngularGearLossMapFile.Init(GetPath(file), tbAngularGearLossMapPath.Text)
 
 		veh.VehicleCategory = CType(CbCat.SelectedValue, VehicleCategory) 'CType(CbCat.SelectedIndex, tVehCat)
@@ -460,11 +460,11 @@ Public Class VehicleForm
 			veh.Axles.Add(a0)
 		Next
 
-		veh.PTOType = CType(cbPTOType.SelectedValue, String)
-		veh.PTOLossMap.Init(GetPath(file), tbPTOLossMap.Text)
-		veh.PTOCycle.Init(GetPath(file), tbPTOCycle.Text)
+		veh.PtoType = CType(cbPTOType.SelectedValue, String)
+		veh.PtoLossMap.Init(GetPath(file), tbPTOLossMap.Text)
+		veh.PtoCycle.Init(GetPath(file), tbPTOCycle.Text)
 
-		veh.MassMax = TbMassMass.Text.ToDouble()
+		veh.MassMax = TbMassMass.Text.ToDouble(0)
 		veh.MassExtra = TbMassExtra.Text.ToDouble(0)
 		veh.AxleConfiguration = CType(CbAxleConfig.SelectedValue, AxleConfiguration)
 
@@ -661,9 +661,9 @@ Public Class VehicleForm
 	Private Sub ButAxlAdd_Click(sender As Object, e As EventArgs) Handles ButAxlAdd.Click
 		_axlDlog.Clear()
 		If _axlDlog.ShowDialog = DialogResult.OK Then
-			LvRRC.Items.Add(CreateListViewItem(LvRRC.Items.Count + 1, _axlDlog.TbAxleShare.Text.ToDouble(),
-												_axlDlog.CbTwinT.Checked, _axlDlog.TbRRC.Text.ToDouble(), _axlDlog.TbFzISO.Text.ToDouble(),
-												_axlDlog.CbWheels.Text, _axlDlog.TbI_wheels.Text.ToDouble()))
+			LvRRC.Items.Add(CreateListViewItem(LvRRC.Items.Count + 1, _axlDlog.TbAxleShare.Text.ToDouble(0),
+												_axlDlog.CbTwinT.Checked, _axlDlog.TbRRC.Text.ToDouble(0), _axlDlog.TbFzISO.Text.ToDouble(0),
+												_axlDlog.CbWheels.Text, _axlDlog.TbI_wheels.Text.ToDouble(0)))
 			Change()
 			DeclInit()
 
diff --git a/VECTO/Input Files/Engine.vb b/VECTO/Input Files/Engine.vb
index 92be9b1eef..68a7383b55 100644
--- a/VECTO/Input Files/Engine.vb	
+++ b/VECTO/Input Files/Engine.vb	
@@ -14,6 +14,7 @@ Imports System.IO
 Imports System.Linq
 Imports Newtonsoft.Json.Linq
 Imports TUGraz.VECTO.Input_Files
+Imports TUGraz.VectoCommon.Exceptions
 Imports TUGraz.VectoCommon.InputData
 Imports TUGraz.VectoCommon.Models
 Imports TUGraz.VectoCommon.Utils
@@ -134,8 +135,8 @@ Public Class Engine
 		_fuelConsumptionMapPath.Clear()
 		_fullLoadCurvePath.Clear()
 
-		WHTCurbanInput = 0
-		WHTCruralInput = 0
+		WHTCUrbanInput = 0
+		WHTCRuralInput = 0
 		WHTCMotorwayInput = 0
 		WHTCEngineeringInput = 1
 	End Sub
@@ -153,7 +154,7 @@ Public Class Engine
 		If validationResults.Count > 0 Then
 			Dim messages As IEnumerable(Of String) =
 					validationResults.Select(Function(r) r.ErrorMessage + String.Join(", ", r.MemberNames.Distinct()))
-			MsgBox("Invalid input." + Environment.NewLine + String.Join("; ", messages), MsgBoxStyle.OkOnly,
+			MsgBox("Invalid input." + Environment.NewLine + String.Join(Environment.NewLine, messages), MsgBoxStyle.OkOnly,
 					"Failed to save gearbox")
 			Return False
 		End If
@@ -182,9 +183,9 @@ Public Class Engine
 
 		body.Add("FuelMap", _fuelConsumptionMapPath.PathOrDummy)
 
-		body.Add("WHTC-Urban", WHTCurbanInput)
-		body.Add("WHTC-Rural", WHTCruralInput)
-		body.Add("WHTC-Motorway", WHTCmotorwayInput)
+		body.Add("WHTC-Urban", WHTCUrbanInput)
+		body.Add("WHTC-Rural", WHTCRuralInput)
+		body.Add("WHTC-Motorway", WHTCMotorwayInput)
 		body.Add("ColdHotBalancingFactor", ColdHotBalancingFactorInput)
 
 		json.Content = JToken.FromObject(New Dictionary(Of String, Object) From {{"Header", header}, {"Body", body}})
@@ -378,13 +379,17 @@ Public Class Engine
 
 	Public ReadOnly Property FuelConsumptionMap As TableData Implements IEngineDeclarationInputData.FuelConsumptionMap
 		Get
-			Return VectoCSVFile.Read(_fuelConsumptionMapPath.OriginalPath)
+			If Not File.Exists(_fuelConsumptionMapPath.FullPath) Then _
+				Throw New VectoException("FuelConsumptionMap is missing or invalid")
+			Return VectoCSVFile.Read(_fuelConsumptionMapPath.FullPath)
 		End Get
 	End Property
 
 	Public ReadOnly Property FullLoadCurve As TableData Implements IEngineDeclarationInputData.FullLoadCurve
 		Get
-			Return VectoCSVFile.Read(_fullLoadCurvePath.OriginalPath)
+			If Not File.Exists(_fullLoadCurvePath.FullPath) Then _
+				Throw New VectoException("Full-Load Curve is missing or invalid")
+			Return VectoCSVFile.Read(_fullLoadCurvePath.FullPath)
 		End Get
 	End Property
 
diff --git a/VECTO/Input Files/Gearbox.vb b/VECTO/Input Files/Gearbox.vb
index 996aaa3cae..6f5deab068 100644
--- a/VECTO/Input Files/Gearbox.vb	
+++ b/VECTO/Input Files/Gearbox.vb	
@@ -12,6 +12,7 @@ Imports System.Collections.Generic
 Imports System.ComponentModel.DataAnnotations
 Imports System.IO
 Imports System.Linq
+Imports System.Runtime.CompilerServices
 Imports Newtonsoft.Json.Linq
 Imports TUGraz.VECTO.Input_Files
 Imports TUGraz.VectoCommon.InputData
@@ -21,6 +22,7 @@ Imports TUGraz.VectoCore.InputData.FileIO.JSON
 Imports TUGraz.VectoCore.InputData.Impl
 Imports TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 Imports TUGraz.VectoCore.Models.SimulationComponent.Data
+Imports TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 Imports TUGraz.VectoCore.Utils
 
 <CustomValidation(GetType(Gearbox), "ValidateGearbox")>
@@ -250,8 +252,9 @@ Public Class Gearbox
 
 		Try
 			'Dim vectoJob As VectoJob = New VectoJob() With {.FilePath = VectoJobForm.VECTOfile}
+			Dim vectoFile As String = VectoJobForm.VectoFile
 			Dim inputData As IEngineeringInputDataProvider =
-					TryCast(JSONInputDataFactory.ReadComponentData(VectoJobForm.VECTOfile), 
+					TryCast(JSONInputDataFactory.ReadComponentData(vectoFile), 
 							IEngineeringInputDataProvider)
 			'Dim vehicle As IVehicleEngineeringInputData = inputData.VehicleInputData
 			Dim engine As CombustionEngineData
@@ -259,13 +262,22 @@ Public Class Gearbox
 			If mode = ExecutionMode.Declaration Then
 				Dim doa As DeclarationDataAdapter = New DeclarationDataAdapter()
 
-				engine = doa.CreateEngineData(inputData.EngineInputData, gearbox.Type)
+				Try
+					engine = doa.CreateEngineData(inputData.EngineInputData, gearbox.Type)
+				Catch
+					engine = GetDefaultEngine()
+				End Try
 
 				axlegearData = doa.CreateAxleGearData(gearbox, False)
 				gearboxData = doa.CreateGearboxData(gearbox, engine, axlegearData.AxleGear.Ratio, rdyn, False)
 			Else
 				Dim doa As EngineeringDataAdapter = New EngineeringDataAdapter()
-				engine = doa.CreateEngineData(inputData.EngineInputData, gearbox)
+				Try
+					engine = doa.CreateEngineData(inputData.EngineInputData, gearbox)
+				Catch
+					engine = GetDefaultEngine()
+				End Try
+
 				axlegearData = doa.CreateAxleGearData(gearbox, True)
 				gearboxData = doa.CreateGearboxData(gearbox, engine, axlegearData.AxleGear.Ratio, rdyn, True)
 			End If
@@ -290,12 +302,29 @@ Public Class Gearbox
 		End Try
 	End Function
 
+	Private Shared Function GetDefaultEngine() As CombustionEngineData
+		Dim fldData As MemoryStream = New MemoryStream()
+		Dim writer As StreamWriter = New StreamWriter(fldData)
+		writer.WriteLine("engine speed, full load torque, motoring torque")
+		writer.WriteLine(" 500, 2000, -500")
+		writer.WriteLine("2500, 2000, -500")
+		writer.Flush()
+		fldData.Seek(0, SeekOrigin.Begin)
+
+		Dim fldCurve As EngineFullLoadCurve = EngineFullLoadCurve.Create(VectoCSVFile.ReadStream(fldData))
+		Return New CombustionEngineData() With {
+			.IdleSpeed = 600.RPMtoRad(),
+			.FullLoadCurve = fldCurve
+			}
+	End Function
+
 
 	Public ReadOnly Property SourceType As DataSourceType Implements IComponentInputData.SourceType
 		Get
 			Return DataSourceType.JSONFile
 		End Get
 	End Property
+
 	Public ReadOnly Property Source As String Implements IComponentInputData.Source
 		Get
 			Return FilePath
@@ -502,13 +531,14 @@ Public Class Gearbox
 
 	Public ReadOnly Property LossMap As TableData Implements IAxleGearInputData.LossMap
 		Get
-			Return VectoCSVFile.Read(GearLossmaps(0).PathOrDummy)
+			If Not File.Exists(GearLossmaps(0).FullPath) Then Return Nothing
+			Return VectoCSVFile.Read(GearLossmaps(0).FullPath)
 		End Get
 	End Property
 
 	Public ReadOnly Property Efficiency As Double Implements IAxleGearInputData.Efficiency
 		Get
-			Return GearLossMap(0, True).ToDouble()
+			Return GearLossMap(0, True).ToDouble(0)
 		End Get
 	End Property
 End Class
diff --git a/VECTO/Input Files/VectoJob.vb b/VECTO/Input Files/VectoJob.vb
index d8af67211e..7eb0020e01 100644
--- a/VECTO/Input Files/VectoJob.vb	
+++ b/VECTO/Input Files/VectoJob.vb	
@@ -113,7 +113,7 @@ Public Class VectoJob
 		If validationResults.Count > 0 Then
 			Dim messages As IEnumerable(Of String) =
 					validationResults.Select(Function(r) r.ErrorMessage + String.Join(", ", r.MemberNames.Distinct()))
-			MsgBox("Invalid input." + Environment.NewLine + String.Join("; ", messages), MsgBoxStyle.OkOnly,
+			MsgBox("Invalid input." + Environment.NewLine + String.Join(Environment.NewLine, messages), MsgBoxStyle.OkOnly,
 					"Failed to save Vecto Job")
 			Return False
 		End If
@@ -552,7 +552,9 @@ Public Class VectoJob
 			If Not File.Exists(_driverAccelerationFile.FullPath) Then
 				Try
 					Dim cycleDataRes As Stream =
-							RessourceHelper.ReadStream(RessourceHelper.Namespace + "VACC." + _driverAccelerationFile.OriginalPath + VectoCore.Configuration.Constants.FileExtensions.DriverAccelerationCurve)
+							RessourceHelper.ReadStream(
+								RessourceHelper.Namespace + "VACC." + _driverAccelerationFile.OriginalPath +
+								VectoCore.Configuration.Constants.FileExtensions.DriverAccelerationCurve)
 					Return VectoCSVFile.ReadStream(cycleDataRes)
 				Catch ex As Exception
 					Return Nothing
@@ -615,7 +617,20 @@ Public Class VectoJob
 		vectoJob._engineInputData = New JSONComponentInputData(vectoJob._engineFile.FullPath)
 		vectoJob._gearboxInputData = New JSONComponentInputData(vectoJob._gearboxFile.FullPath)
 
+
 		Dim result As IList(Of ValidationResult) = New List(Of ValidationResult)
+
+		If vectoJob._vehicleInputData.VehicleInputData Is Nothing Then _
+			result.Add(New ValidationResult("Vehicle File is missing or invalid"))
+		If vectoJob._engineInputData.EngineInputData Is Nothing Then _
+			result.Add(New ValidationResult("Engine File is missing or invalid"))
+		If vectoJob._gearboxInputData.GearboxInputData Is Nothing Then _
+			result.Add(New ValidationResult("Gearbox File is missing or invalid"))
+
+		If result.Any() Then
+			Return _
+				New ValidationResult("Vecto Job Configuration is invalid. ", result.Select(Function(r) r.ErrorMessage).ToList())
+		End If
 		Try
 			If mode = ExecutionMode.Declaration Then
 				If Not vectoJob._vehicleInputData.VehicleInputData.SavedInDeclarationMode Then
diff --git a/VECTO/Input Files/Vehicle.vb b/VECTO/Input Files/Vehicle.vb
index 9b1c302c2e..d67e58fa65 100644
--- a/VECTO/Input Files/Vehicle.vb	
+++ b/VECTO/Input Files/Vehicle.vb	
@@ -84,8 +84,8 @@ Public Class Vehicle
 		AngularGearLossMapFile = New SubPath()
 
 		Axles = New List(Of Axle)
-		PTOLossMap = New SubPath()
-		PTOCycle = New SubPath()
+		PtoLossMap = New SubPath()
+		PtoCycle = New SubPath()
 		SetDefault()
 	End Sub
 
@@ -132,13 +132,15 @@ Public Class Vehicle
 					New ValidationResult("Retarder Configuration is invalid. ", result.Select(Function(r) r.ErrorMessage).ToList())
 			End If
 
-			result = angledriveData.Validate(If(Cfg.DeclMode, ExecutionMode.Declaration, ExecutionMode.Engineering))
-			If result.Any() Then
-				Return _
-					New ValidationResult("AngleDrive Configuration is invalid. ", result.Select(Function(r) r.ErrorMessage).ToList())
+			If vehicle.AngularGearType = AngularGearType.SeparateAngularGear Then
+				result = angledriveData.Validate(If(Cfg.DeclMode, ExecutionMode.Declaration, ExecutionMode.Engineering))
+				If result.Any() Then
+					Return _
+						New ValidationResult("AngleDrive Configuration is invalid. ", result.Select(Function(r) r.ErrorMessage).ToList())
+				End If
 			End If
 
-			If Not ptoData Is Nothing Then
+			If Not vehicle.PTOTransmissionType = "None" Then
 				result = ptoData.Validate(If(Cfg.DeclMode, ExecutionMode.Declaration, ExecutionMode.Engineering))
 				If result.Any() Then
 					Return _
@@ -174,9 +176,9 @@ Public Class Vehicle
 		AngularGearLossMapFile.Clear()
 		AngularGearRatio = 1
 
-		PTOType = PTOTransmission.NoPTO
-		PTOLossMap.Clear()
-		PTOCycle.Clear()
+		PtoType = PTOTransmission.NoPTO
+		PtoLossMap.Clear()
+		PtoCycle.Clear()
 
 		Axles.Clear()
 		VehicleCategory = VehicleCategory.RigidTruck	'tVehCat.Undef
@@ -196,7 +198,7 @@ Public Class Vehicle
 		If validationResults.Count > 0 Then
 			Dim messages As IEnumerable(Of String) =
 					validationResults.Select(Function(r) r.ErrorMessage + String.Join(", ", r.MemberNames.Distinct()))
-			MsgBox("Invalid input." + Environment.NewLine + String.Join("; ", messages), MsgBoxStyle.OkOnly,
+			MsgBox("Invalid input." + Environment.NewLine + String.Join(Environment.NewLine, messages), MsgBoxStyle.OkOnly,
 					"Failed to save vehicle")
 			Return False
 		End If
@@ -230,9 +232,9 @@ Public Class Vehicle
 				{"Ratio", AngularGearRatio},
 				{"LossMap", AngularGearLossMapFile.PathOrDummy}}},
 				{"PTO", New Dictionary(Of String, Object) From {
-				{"Type", PTOType},
-				{"LossMap", PTOLossMap.PathOrDummy},
-				{"Cycle", PTOCycle.PathOrDummy}}},
+				{"Type", PtoType},
+				{"LossMap", PtoLossMap.PathOrDummy},
+				{"Cycle", PtoCycle.PathOrDummy}}},
 				{"AxleConfig", New Dictionary(Of String, Object) From {
 				{"Type", AxleConfiguration.GetName()},
 				{"Axles", (From axle In Axles Select New Dictionary(Of String, Object) From {
-- 
GitLab