diff --git a/ConfigParser.cs b/ConfigParser.cs
index 5227b2f78ceeb5ec6e5778ba4bf0019c624ddca1..a928747729578ad1ef7a39d21e48639fe23bd0fd 100644
--- a/ConfigParser.cs
+++ b/ConfigParser.cs
@@ -66,35 +66,35 @@ class ConfigDuplicitKeyException: ConfigDuplicitException
 }
 class ConfigNoAmenException: ConfigException
 {
-	public ConfigValue Value;
-	public ConfigNoAmenException(ConfigValue value)
+	public ConfigKeyValue Value;
+	public ConfigNoAmenException(ConfigKeyValue value)
 	{
 		Value = value;
 	}
 	public override string ErrorString()
 	{
-		return $"End string \"{Value.amen}\" for block {Value.Key} starting at line {Value.Line} not found";
+		return $"End string \"{Value.amen}\" for block \"{Value.Key}\" starting at line {Value.Line} not found";
 	}
 }
 class ConfigMixedTabException: ConfigException
 {
-	public ConfigValue Value;
+	public ConfigKeyValue Value;
 	public int Line;
-	public ConfigMixedTabException(ConfigValue value, int line)
+	public ConfigMixedTabException(ConfigKeyValue value, int line)
 	{
 		Value = value;
 		Line = line;
 	}
 	public override string ErrorString()
 	{
-		return $"{Line}: {Value.FullName}: Combination of tabs and spaces is not supported.";
+		return $"{Value.Place}: Combination of tabs and spaces is not supported.";
 	}
 }
 class ConfigWrongIndentException: ConfigException
 {
-	public ConfigValue? Value;
+	public ConfigKeyValue? Value;
 	public int Line;
-	public ConfigWrongIndentException(ConfigValue? value, int line)
+	public ConfigWrongIndentException(ConfigKeyValue? value, int line)
 	{
 		Value = value;
 		Line = line;
@@ -103,7 +103,7 @@ class ConfigWrongIndentException: ConfigException
 	{
 		if(Value == null)
 			return $"{Line}: Wrong indent.";
-		return $"{Line}: {Value.FullName}: Wrong indent.";
+		return $"{Value.Place}: Wrong indent.";
 	}
 }
 class ConfigSectionNotDefinedException: ConfigException
@@ -115,7 +115,7 @@ class ConfigSectionNotDefinedException: ConfigException
 	}
 	public override string ErrorString()
 	{
-		return $"Section {Name} is not defined.";
+		return $"Section \"{Name}\" is not defined.";
 	}
 }
 class ConfigNotDefinedException: ConfigException
@@ -129,7 +129,7 @@ class ConfigNotDefinedException: ConfigException
 	}
 	public override string ErrorString()
 	{
-		return $"{Section.SectionName ?? "[global]"}: Attribute {Name} is not defined.";
+		return $"{Section.SectionName ?? "[global]"}: Option \"{Name}\" is not defined.";
 	}
 }
 class ConfigNoValueException: ConfigException
@@ -143,22 +143,21 @@ class ConfigNoValueException: ConfigException
 	}
 	public override string ErrorString()
 	{
-		return $"{Value.Line}: Attribute {Value.FullName} need value." ;
+		return $"{Value.Place}: Value needed." ;
 	}
 }
-class ConfigParseAttributeException: ConfigException
+class ConfigParseValueException: ConfigException
 {
 	public ConfigValue Value;
 	public string? Reason;
-	public ConfigParseAttributeException(ConfigValue value, string? reason=null)
+	public ConfigParseValueException(ConfigValue value, string? reason=null)
 	{
 		Value = value;
 		Reason = reason;
 	}
 	public override string ErrorString()
 	{
-		string name = Value.Section.SectionName != null ? $"{Value.Section.SectionName}: {Value.Key}" : Value.Key;
-		return $"{Value.Line}: Parsing attribute {Value.FullName} fail" +
+		return $"{Value.Place}: Parsing fail" +
 			(Reason==null?".":$": {Reason}.");
 	}
 }
@@ -173,24 +172,19 @@ class ConfigMistake: ConfigException
 	}
 	public override string ErrorString()
 	{
-		string name = Value.Section.SectionName != null ? $"{Value.Section.SectionName}: {Value.Key}" : Value.Key;
-		return $"{Value.Line}: {Value.FullName}: {Text}";
+		return $"{Value.Place}: {Text}";
 	}
 }
 
-class ConfigValue
+abstract class ConfigValue
 {
-	public ConfigSection Section {get; init;}
-	internal string? amen;
-	internal string? tabs;
-	public string Key {get; init;}
+	public int Line;
 	internal string? Value;
 	public bool HasText() => Value != null;
-	public int Line;
-	public string FullName
-	{
-		get => Section.SectionName != null ? $"{Section.SectionName}: {Key}" : Key;
-	}
+
+	public virtual string Place{get => $"{Line}: {FullName}";}
+	public abstract string FullName{get;}   // For showing in error
+
 	public string AsString()
 	{
 		if(Value == null) throw new ConfigNoValueException(this);
@@ -235,7 +229,7 @@ class ConfigValue
 			return System.Drawing.ColorTranslator.FromHtml(AsString());
 		} catch (ArgumentException)
 		{
-			throw new ConfigParseAttributeException(this, "String is not color");
+			throw new ConfigParseValueException(this, "String is not color");
 		}
 	}
 	public bool AsBool()
@@ -246,7 +240,7 @@ class ConfigValue
 			return true;
 		if(v == "false" || v == "no" || v == "unuse" || v == "0")
 			return false;
-		throw new ConfigParseAttributeException(this, "String is not bool");
+		throw new ConfigParseValueException(this, "String is not bool");
 
 	}
 	public double AsDouble()
@@ -256,7 +250,7 @@ class ConfigValue
 			return double.Parse(AsString());
 		} catch (FormatException)
 		{
-			throw new ConfigParseAttributeException(this, "String is not number");
+			throw new ConfigParseValueException(this, "String is not number");
 		}
 	}
 	public int AsInt()
@@ -266,7 +260,7 @@ class ConfigValue
 			return int.Parse(AsString());
 		} catch (FormatException)
 		{
-			throw new ConfigParseAttributeException(this, "String is not int");
+			throw new ConfigParseValueException(this, "String is not int");
 		}
 	}
 	public int AsMs()
@@ -278,34 +272,86 @@ class ConfigValue
 		return new ConfigParser(AsString(), Line);
 	}
 	public static implicit operator string(ConfigValue v) => v.AsString();
-	internal ConfigValue(ConfigSection _Section, string _Key, int _line)
+}
+class ConfigKeyValue: ConfigValue
+{
+	public ConfigSection Section {get; init;}
+	internal string? amen;
+	internal string? tabs;
+	public string Key {get; init;}
+	public override string FullName
+	{
+		get => Section.SectionName != null ? $"{Section.SectionName}: {Key}" : Key;
+	}
+	internal ConfigKeyValue(ConfigSection _Section, string _Key, int _line)
 	{
 		Section = _Section;
 		Key = _Key;
 		Line = _line;
 	}
+	public ConfigKeyAsValue KeyAsValue() => new(this);
 }
-class ConfigSection: IReadOnlyList<ConfigValue>
+class ConfigKeyAsValue: ConfigValue
+{
+	public ConfigSection Section {get; init;}
+	public override string FullName
+	{
+		get => (Section.SectionName != null ? $"{Section.SectionName}: " : "") + $"Key {Value}";
+	}
+	internal ConfigKeyAsValue(ConfigKeyValue keyValue)
+	{
+		Line = keyValue.Line;
+		Value = keyValue.Key;
+		Section = keyValue.Section;
+	}
+}
+class ConfigSectionNameAsValue: ConfigValue
+{
+	public ConfigSection Section {get; init;}
+	public override string FullName
+	{
+		get => "Section name " + (Section.SectionName != null ? $"\"{Section.SectionName}\"" : "of main section");
+	}
+	internal ConfigSectionNameAsValue(ConfigSection _Section)
+	{
+		Section = _Section;
+		Value = Section.SectionName;
+		Line = Section.Line;
+	}
+}
+class ConfigSectionNameAsDefaultValue: ConfigSectionNameAsValue
+{
+	protected string defaultFor;
+	internal ConfigSectionNameAsDefaultValue(ConfigSection _Section, string _defaultFor): base(_Section)
+	{
+		defaultFor = _defaultFor;
+	}
+	public override string FullName
+	{
+		get => base.FullName + $" as default for \"{defaultFor}\" option";
+	}
+}
+class ConfigSection: IReadOnlyList<ConfigKeyValue>
 {
 	public ConfigParser Root {get; init;}
 	public string? SectionName {get; init;}
 	public int Line;
-	List<ConfigValue> values = new();
-	Dictionary<string, ConfigValue> valueByName = new();
+	List<ConfigKeyValue> values = new();
+	Dictionary<string, ConfigKeyValue> valueByName = new();
 	internal ConfigSection(ConfigParser _Root, string? _SectionName, int _line)
 	{
 		Root = _Root;
 		SectionName = _SectionName;
 		Line = _line;
 	}
-	internal void Add(ConfigValue v)
+	internal void Add(ConfigKeyValue v)
 	{
 		if(valueByName.ContainsKey(v.Key))
 			throw new ConfigDuplicitKeyException(v.Key, v.Line, valueByName[v.Key].Line);
 		valueByName[v.Key] = v;
 		values.Add(v);
 	}
-	public IEnumerator<ConfigValue> GetEnumerator()
+	public IEnumerator<ConfigKeyValue> GetEnumerator()
 	{
 		foreach(var s in values)
 			yield return s;
@@ -313,21 +359,25 @@ class ConfigSection: IReadOnlyList<ConfigValue>
 	System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
 		=> GetEnumerator();
 	public int Count{ get{return values.Count;}}
-	public ConfigValue this[int i]
+	public ConfigKeyValue this[int i]
 	{
 		get { return values[i]; }
 	}
-	public ConfigValue? this[string key]
+	public ConfigKeyValue? this[string key]
 	{
 		get { return Optional(key); }
 	}
-	public ConfigValue? Optional(string key)
+	public ConfigKeyValue? Optional(string key)
 	{
 		if(!valueByName.TryGetValue(key, out var r))
 			return null;
 		return r;
 	}
-	public ConfigValue Mandatory(string key)
+	public ConfigValue OptionalDefaultIsSectionName(string key)
+	{
+		return (ConfigValue?)Optional(key) ?? new ConfigSectionNameAsDefaultValue(this, key);
+	}
+	public ConfigKeyValue Mandatory(string key)
 	{
 		if(!valueByName.TryGetValue(key, out var r))
 			throw new ConfigNotDefinedException(this, key);
@@ -345,6 +395,7 @@ class ConfigSection: IReadOnlyList<ConfigValue>
 			w.WriteLine($"'{x.Key}' = '{(x.HasText() ? x.AsString() : "null")}'");
 		}
 	}
+	public ConfigSectionNameAsValue SectionNameAsValue() => new(this);
 }
 class ConfigParser: IReadOnlyList<ConfigSection>
 {
@@ -355,7 +406,7 @@ class ConfigParser: IReadOnlyList<ConfigSection>
 	{
 		string[] lines = s.Split("\n");
 		var currentSection = MainSection = new(this, null, 0);
-		ConfigValue? lastVal = null;
+		ConfigKeyValue? lastVal = null;
 		for(int i=0;i<lines.Count();i++)
 		{
 			string l = lines[i];
@@ -408,12 +459,12 @@ class ConfigParser: IReadOnlyList<ConfigSection>
 			int indexArrow = l.IndexOf("<<");
 			if(indexIs == -1 && indexArrow == -1)
 			{
-				currentSection.Add(lastVal = new ConfigValue(currentSection, tl, firstLineIndex + i));
+				currentSection.Add(lastVal = new ConfigKeyValue(currentSection, tl, firstLineIndex + i));
 				continue;
 			}
 			int index = indexIs == -1 ? indexArrow : indexArrow == -1 ? indexIs : Math.Min(indexIs, indexArrow);
 			string key = l[0..index].Trim();
-			currentSection.Add(lastVal = new ConfigValue(currentSection, key, firstLineIndex + i));
+			currentSection.Add(lastVal = new ConfigKeyValue(currentSection, key, firstLineIndex + i));
 			if(indexIs != -1 && (indexArrow == -1 || indexIs < indexArrow))
 			{
 				string val = l[(indexIs+1)..].Trim();