Conditional execution (new style)
Conditional execution (old style)
List of Plattformspecific functions/restrictions
A word about CONFIG.SYS and AUTOEXEC.BAT
Mtwin uses Command files (Extension CMD), which contain the commands for modifications that should be made to a given INI file.
Usage: mtwin [options] /c <ICM-file> [options] mtwin [options] <INI-file> [options] <CMD-file> [options] mtwin [options] /g <GRP-file> [options] <CMD-file> [options] mtwin [options] {/c/d} <GRP-file> [options] <GRI-file> [options] Options: starts with - or / /? Display short online help-screen /b Create Backupfile /c Compile GRI into GRP file When only one filename is specified, a ICM file is used /d Decompile GRP into GRI file /e=<char> Use <char> instead of = as delimitter between keys & val. /g GRP & CMD file /h Display short online help-screen /l=<file> Log messages to file /n=<file> Creates INI files, if it not already exists. When the /n option is not specified, and the INI file does not exist, then nothing is processed. When a filename is specified, then, when the original- inifile does not exist, the new INI is created based on the content of the specified file. /s[0-3] Swap GRP-Header /s0 Iconname is sectionheader /s Command is sectionheader /s1 Command is sectionheader /s2 Only EXE-name of prg is sectionheader /s3 Complete path+EXE name is section header /v[0-9] Verbose mode, default value is /v3 /v0 Display no messages /v9 Display all messages /w[0-2] NET.CFG is processed instead of INI-file /w Process file with NET.CFG rules /w0 Process file with INI rules /w1 Process file with NET.CFG rules /w2 Process file with .BAT & CONFIG.SYS rules
If you want to modify multiple INI files, you can create an ICM (Ini Command File). Each line of this file contains an INI file filename and a Command file filename.
; Example ICM File
;
C:\WINDOWS\WIN.INI C:\UT\WIN.CMD
C:\WINDOWS\SYSTEM.INI C:\UT\SYSTEM.CMD
;
A backup of the INI-File with the extension .BAK is made before modifying the file. If the /b parameter is specified, the backup file is not deleted after processing.
When decompiling GRP files, normaly the Icon-name (as displayed in the group) is used as the section-name. When your users change the Iconnames, then you can use the /s option, to specify that the EXE-Name is used as section-name, instead of the Iconname. Of course, when recompiling the GRI file, you must use the same option.
All lines which begin with ; are treated as comments.
Normally all section names, keys and values are NOT case sensitive. However, _ and * give the possibility for case sensitive matching.
MTWIN can process INI files of any size, even larger than 64 kBytes. However, a dynamic list of all commands within a CMD file is created in memory as it is loaded from the command line or an ICM file and could reduce available memory temporarily. This is normally not a problem, as you can use more than ??? commands in one CMD file. If this isn't enough, you can split the CMD file and use an ICM file to call the separate CMD files individually.
;
| When this is in front of a line the line is ignored |
-[section]
| The corresponding section is deleted |
-[section]Key
| The Key in section will be deleted |
-[section]Key=Value
| The Key is only deleted if the Value matches exactly. This is used to delete device=... lines in system.ini |
_[section]Key=Value
| Same as - but Value is case sensitive. Normally not used. |
~[section]Key=Value
| Used to delete Keys, when the Key is terminated by a numeric value. (Used to delete Groups in PROGMAN.INI) |
#[section]
| The corresponding section is commented |
#[section]Key
| The Key in section will be commented |
#[section]Key=Value
| The Key is only commented if the Value matches exactly. This is used to comment device=... lines in system.ini |
@[section]
| The ; in front of the corresponding section is removed |
@[section]Key
| The ; in front of the Key in section is removed |
@[section]Key=Value
| The ; in front of the Key is removed, if the Value matches exactly. This is used to uncomment device=... lines in system.ini |
+[Section]Key
| Adds Key in Section, a = sign is automtically added, unless it is a NET.CFG file. |
=+[Section]Key
| Adds Key in Section, with NO trailing = |
+[Section]Key=
| Adds Key in Section. |
+[Section]Key=Value
| Adds Key and Value to section. |
?+[Section]Key=Value
| Adds Key and Value to section, but ONLY if the key does not currently exist. |
&[Section]Key=Value
| This Key/Value is always inserted, even if already a key exists, but with a different value. Used to insert device=... lines in System.ini |
*[Section]Key=Value
| Same as &, but the value is case sensitive Normally not used. |
![Section]Key=Value
| A key is inserted in section, but a numeric value is added to Key, representing the highest+1 value of Key. (Only ?) used for Progman.ini to add new program groups. ~ is used to delete such keys if needed. If the value of the command is already found, then the line is not duplicated. You can add multiple ! entries per Section/Key pair in one pass |
>[Section]Key=Value
| Adds Value to an existing value. The old Value is
preserved and the Value is added at the end of the line. When the values are separated with a , or ; (like network= in system.ini) then you must add a , or ; before the value. Like >[386enh]networks=,vipx.386. The coma sign is then inserted when used. When neither , nor ; is put in front of the Value, then a blank is inserted as separator. |
}[Section]Key=Value
| Same as >, but to avoid comflicts, when creating CMD files from the commandline. Pipe-symbol !!!! |
/[Section]Key=Value
| Same as >, but the Value is inserted in front of all existing values. When the values are separated with a , or ; (like network= in system.ini) then you must add a , or ; sign after the value. Like >[386enh]networks=vipx.386,. The , or ; sign is then inserted when used. When neither a , nor a ; is given, then a blank is used as separator, |
<[Section]Key=Value
| Deletes Value from the Key/Value line. ; , and blanks should be handled correctly. You don't need to specify them in the CMD line. |
{[Section]Key=Value
| Same as <, to avoid problems when creating CMD files from the batch file. |
E commandline
| Execute the given commandline with the command processor When the execution fails, then the variable $_ERRORCODE$ is set to the corresponding errorcode. Execution occurs before processing the INI file. |
EA commandline
| ExecuteAfter, Same as E command, but the command is executed AFTER processing the INI file. The $_ERRORCODE$ variable is not set, since when this is processed, all is already done.... |
O filename.ext
| All output created with the W command is written to this file. A previously opened file is closed. |
r[Section]Original=NewValue
| The string <Original> is replaced with <NewValue>, but only
if [Section] is the current one. If you want to replace theOriginal in ALL sections (even in the section definition) thenspecify [] as the section. When the original value include a = character, then you must enclose it with ".....". When the " character is used as single character, then you must add a \ in front of it. |
R[Section]Original=NewValue
| Same as r command, but the case must match. |
S[Section]Key=<EnvVarname>
| The environment variable with name <EnvVarname> is
setto the Value of this Section/Key. If [Section]Key does not exists, the environment is notmodified. The modification is done in the master environment,which is the one of the FIRST command.com loaded. It is made in the programm environment too.If you use this command under windows, the environmentof the shell inside windows is NOT modified, but whenyou leave windows, the environment has the modified values ! |
W text
| The W command writes the remaining part of the line to the Outputfile previously opened with the O command. |
You can use structured IF-commands. They have the following form:
..
ELSE
..
ENDIF
IF ["NOT"] <condition> { ["AND""OR"] ["NOT"] <condition> }
You can use the NOT keyword, to negate the result of an expression. When you need to combine multiple conditions, then you can use the AND and OR keywords. In some cases you must use ( ) to assign another preference for evaluation. If in a expression you have a ) or " character, then you must enclose the token in " characters. If you need to enclose a " in the token then you must use the \" sequence. The order of NOT, AND , OR are evaluated as in all common computer languages like C, Pascal etc.
NOT affects only the next condition.
AND is always evaluated before a OR condition.
<TRUE> AND <TRUE> OR <FALSE> is the same a (<TRUE> AND <TRUE>) OR <FALSE>
As soon as an expression is defined, the parsing of the rest of the line is aborted. This means, that it is possible that you have an invalid CMD file, but the processing displays no error.
IF FILE EXIST C:\CONFIG.SYS OR UNKNOWN SOMETHING
The evaluation of the expression is stopped just after reading the OR command. Since FILE EXIST returns <TRUE>, there is no need to continue processing the line.
The same is for:
IF FILE EXIST C:\CONFIG.SY AND C:\....
Since the first expression returns FALSE, the part after the AND is not even checked for syntax-errors.
This behaviour is normaly not a problem. Only you must be aware, that when you run MTWIN with such a CMD file, it is probable, that syntax errors are not decovered in a test environment.
The IF's can be nested in the CMD and in the ICM files. The following conditions are currently implemented:
EXIST ENV <value>
NEXIST FILE <filename>
NEXIST DIR <dirname>
NEXIST ENV <value>
VESA == <value> Test for presence of a VESA-Bios (or extension-driver).
VESA != <value> You can use the included utility vesatest.exe to display the string returned by VESA. For the Compaq Advanced
VGA adapter it is : Compaq Adv VGA Ext (512kB Ram) So the line would be: IF VESA == "Compaq Adv VGA Ext (512kB RAM)"
You may have multiple IF commands available to execute command lines based on external values.
In ALL strings, you can insert a sequence $(%...), to replace the text with the content of a DOS environment variable. The old style with %...% is still working, but no longer supported.
+[boot]run=F:\USER\$(%USER)\WINDOWS\CAL.EXE
$(%USER) will be replaced with the value of the USER environment variable.
When It finds a single % in the line the % remains unmodified.
All %% are replaced with a single %. (But %% still works)
Please use the new syntax with $(%...) to reference to environment variables.
Note:
You can use F:\USR\%%USER%%\TEMP to be transformed into F:\USR\%USER%\TEMP. If you simply use F:\USR\%USER%\TEMP it will try to replace %USER% with the corresponding environment variable.
If the specified environment variable does not exist, a warning message is displayed on the screen, and the %...% is removed from the value.
With the 2.22 release of mtwin you can use variables to access some informations from the netware bindery, as well as doing some small operations on them.
A variable is always delimitted with $( ...). All systemvariables begin with $(_ , don't define uservariables with $(_. The variables are not case sensitive. When you need to insert a $ character in your CMD file, then use a $$ to specify, that you mean the $ character and not some variable beginning with $.
To define a variable, use the following syntax:
$(A) := "10"
You can do numeric calculations with variables.
$(A) := $(A) + $(A) ---> 60
$(A) := $(A) - "10" ---> 50
$(B) := "10"$(A) := $(A) + "20" ---> 30
You can concat strings
; Concat of string - variables
;
$(B) := $(B) & "20" --> 1020 concat
$(C) := $(B) + $(A) --> 1080 addition
;
$(_CMDFILE) | Name of the CMD file, without path$(_CMDPATH)
| Path to the CMD file | $(_ERRORCODE)
| Error number (C-Lib) after E command | $(_INIFILE)
| Name of the INI file, without path | $(_INIPATH)
| Path to the INI file | $(_INIVALUE[<section>]<Key>)
| Assigns the value of the given Section/Key | $(_FILEINIVALUE<filename>[<section>]<Key>)
| Same as above, but not the current INI is read, but the given File.
(No blanks are allowed) | $(_MAXNUMKEY[<section>]<Key>)
| Assigns the highest numeric value of the given Section/Key. Used
for GroupX= | $(_FILEMAXNUMKEY<filename>[<section>]<Key>)
| Same as above, but not the current INI is read, but the given File.
(No blanks are allowed) | $(_VESA)
| Returns the String with the VESA drivername | |
$(_NW_LOGINNAME) | Returns the name used at login-time |
$(_NW_FULLNAME) | Returns the full user-name |
$(_NW_LOGINTIME) | The login time-date in the format : YY/MM/DD - HH:MM:SS |
$(_NW_CONNECTION) | Connectionnumber to the server |
$(_NW_OBJID) | Object ID of the user (in Hex-format, as the MAIL directory) |
$(_NW_NICADDR) | Adress of the network interface board |
$(_NW_INETADDR) | Adress of the network segment |
$(%varname) This returns the content of the environment variable.
$(..) variables can be used/created in ICM and CMD files. The value of a once created variable remains, until the EXE file terminates. So you can set values in the ICM file and then use them in the CMD file, or vice-versa.
See the VARIABLE.CMD and OUTFILE.CMD file for an example.
Special note about variables
When processing a ICM file, then following oder is given:
So you see, that the order of the INI-changes is NOT the order in which they are written down in the CMD file. (Most time it is just the reverse order)
When you want to modify GRP (Program Group) files, then you must do the following:
mtwin xx.grp xx.gri -d
mtwin xx.gri xx.cmd
mtwin xx.grp xx.gri -c
With the -d command, you can decompile a GRP file into a GRI (Group INI) file. This file is a simple INI file. On this file you can the do all commands you need to modify your group. With /c finaly you recompile the GRI into a GRP file, which can be loaded by Windows 3.x
When you don't want to do the steps as described above, you can then use simply:
mtwin xx.grp xx.cmd -g
This tells mtwin to do the decompile/modify/recompile in one step, so that you don't need to call mtwin three times.
When you decompile a GRP file, then you get something like this:
Display=SW_SHOWMINIMIZED
UpperLeftX=203
UpperLeftY=7
LowerRightX=518
LowerRightY=476
PosX=546
PosY=430
PRGName=Microsoft Office
[Access]
Command=msaccess.exe
EXEDir=G:\ACCESS\
IconFile=G:\ACCESS\msaccess.exe
IconPosX=246
IconPosY=0
IconNr=0
Path=G:\ACCESS\
[Group Info]
The [Group Info] section has the definition of the position/size and style of the Group-window. The Key PRGName is the name of the Group as displayed in the Windowheader.
For each Icon in the GRP file, a section is created. The section name is the Iconname, when you would like to have something else as Sectionname, then you must use the /s[0-9] option.
nothing or /s0 | Iconname is sectionheader |
/s or /s1 | Command is sectionheader |
/s2 | Only EXE-name of prg is sectionheader |
/s3 | Complete path+EXE name is section header |
Please note, that the EXEDir and the Path must always be terminated with a backslash, otherwise the path is not reconstructed correctly.
EXEDir is the working directory of the Icon, Path it the directory, where the EXE-file is located. When the working directory is the same as the Path, then the Path statement is not required.
When processing INI files, it can be usefull to modify all WIN.INI of all users. To do this, you can use the following syntax (F:\USER\username\WIN\):
mtwin F:\USER\*\WIN\WIN.INI CHANGE.CMD
When you have multiple divisions, then you can even use multiple wild-cards in one line (F:\USER\group\username\WIN):
mtwin F:\USER\*\*\WIN\WIN.INI CHANGE.CMD
In general the functions is identic as with INI files. However there are several differences:
The VIDEO and MONITOR IF-Statements, since this info is not available for such applications applications.
The SETENV and VESA functions are not implemented under WIN16 since these functions are not possible with WIN16.
Currently the NETWARE functions need to load the NWCALLS.DLL. When you don't have the NW Client installed, then you can simply use the NWCALLS.DLL how is shipped with this utility. The message about the missing NET.MSG can be ignored. Ask me for a version without netware support if this is a problem for you.
The VIDEO and MONITOR IF-Statements, do not work under WIN32, since this info is not available for such applications applications. Perhaps in future versions this will return the entry of the registery....
The SETENV and VESA functions are not implemented under WIN32 since these functions are not possible with WIN32.
Currently the NETWARE functions are implemented under Windows 95. But they work only when you use the Novell Netware client.
When you don't need Netware support (means when you don't have the Novell client installed), then you should download the MTWIN95N.EXE file which has no netware support build in.
The VIDEO and MONITOR IF-Statements, do not work under OS/2, since this info is not available for OS/2 applications.
The SETENV and VESA functions are not implemented under OS/2 since these functions are not possible with OS/2.
Currently the NETWARE requester for OS/2 must be installed, otherwise it will not run. (Or at least the NWCALL.DLL !!!!). There exists a OS/2 version without any netware support so you won't need the netware DLL's. This file is called MTWOS2N.EXE.
The NLM version of MTWIN is not intended for productional servers. It's more a study of myself for writting portable C++ code for different plattforms. When the NLM is running, no process-sheduling is taking place, so please don't process too big ICM or INI files.
I have however not been able to crash a 3.12 server with my MTWIN.NLM, so it seems to work very stable. But I won't guarrantee that it always behaves in this safe condition.
Wildcards for filenames are not supported under Netware.
The VIDEO and MONITOR IF-Statements, do not work under Netware, since this info are not available for Netware lodable modules.
The SETENV and VESA functions are not implemented under Netware since these functions are not possible with NLM's.
All the Netware functions are currently not available too.
Function | DOS | Windows 3.x | Windows NT/95 | OS/2 | NLM |
MONITOR | Yes | No | No | No | No |
VIDEO | Yes | No | No | No | No |
VESA | Yes | No | No | No | No |
SetEnv | Yes | Yes | Yes | Yes | No |
Wildcards | Yes | Yes | Yes | Yes | No |
The DLL version of this utility is NOT eMailware. But it is available for 200.-- SFr. or 150 US$
If you need a library (Watcom C++), then you can get it too, for 400.-- SFr. or 270 US$
If you need the source code to be able to rebuild it yourself, 650.-- SFr. or 500 US$ (But you will not have the right to include the source for other products, not even in compiled form.
If you would have the source code without any restrictions, then you must pay me 2'000.-- SFr. or 1'500 US$ (The only restriction is, that you don't have the right to redistribute the source without major changes made on it.)
In these prices, there is included an update to all versions I will release for one year, and support for the usage of the product for one year too.
The products are distributed at no fee via electronic mail. If you need a postal delivery, then add 15 SFr. (10 US$) for europe and 15$ for shipping outside europe. If you need something faster than normal postal delivery, then ask me for the taxes.
Please look at the different CMD and ICM files included.
ENV.CMD | Some evaluation of environment variablesFILE.ICM
| Some IF commands in a ICM file | ININI.CMD
| Samples for the ININI keyword | NET.CMD
| What you can do to modify netware client files | NIF.ICM
| Shows the use of nested ICM commands | PROGMAN.CMD
| Shows commands to add/remove groups | PS.CFG PS.CMD
| Example to change CFG files who have a special
(:) delimitter | OUTFILE.CMD
| Examples for creating secondary files, and
executing files | SYSNET.CMD
| Adds network support for WfWG 3.11 on Laptops | SYSNNET.CMD
| Removes network support for WfWG 3.11 on
Laptops | VARIABLE.CMD
| An example what you can do with variables | VESA.CMD
| An example using the VESA keyword | |
![Section]Key=ValueZ
[Section] [Section]
Key1=Value1 Key1=Value1
Key2=Value2 Key2=Value2
Key3=Value3 Key3=Value3
Key4=ValueZ
>[Section]Key=Value1
[Section] [Section]
Key=Value0 Key=Value0 Value1
>[Section]Key=,Value1
[Section] [Section]
Key=Value0 Key=Value0,Value1
/[Section]Key=Value1,
[Section] [Section]
Key=Value0 Key=Value1,Value0
<[Section]Key=Value1
[Section] [Section]
Key=Value0,Value1 Key=Value0
IFMEMBER MANAGER ![Groups]Group=LAFW.GRP
Adds GroupXX=LAFW.GRP only if the user is member of the group MANAGER
IFENV %USER% SSCA +[Windows]Supervisor=True
Sets Supervisor=True, when the environment variable USER is equal to SSCA
+[boot]run=F:\USER\%USER%\WINDOWS\CAL.EXE
%USER% will be replaced with the value of the USER - Environment variable.
+[boot]run=F:\USER\%%USER%%\WINDOWS\CAL.EXE
gives run=F:\USER\%USER%\WINDOWS\CAL.EXE.
r[][OldSectionName]=[NewSectionName]
This command renames a section heading. Mtwin then looks in each line for the Old-name and if found, it replaces it with the new name. You should include the [..] to be sure that only section headings are replaced.
- Modifying device= lines in the SYSTEM.INI file. This is the only place where multiple keys exist that have the same name. To handle this special situation you MUST use the & command instead of the + command. When you do modifications with the + command, then either all device= lines have the same value, or/and some keys are added multiple times.
- With the r command it is very easy to move a program/library to a new location. Of course you must take care to correct all other references to that location. (In the registration database OLE, in DDE-statements and of course the program icon(s) in the program manager.)
The current version of MTWIN has NO built-in support for SYS and BAT files !!!!
But with some care you can still make modifications to your system files, just treat them like NET.CFG files !!!!! For .BAT files I would recommend you to specify the /w2 option, perhaps for config.sys file, this is the better option too, just try what gives the better results. The section-header is then selected in another fashion, which is more accurate for BAT files.
MTWIN /W CONFIG.SYS CONFIG.CMD
--------- CONFIG.CMD -----------
&[]device=C:\DOS\ANSI.SYS
+[]files=175
--------------------------------
This inserts the ANSI.SYS driver after the last line of your SYS file, but only if it not already exists. When you use the [COMMON] sections for menus in CONFIG.SYS, then just treat it like a normal INI file.
--------- AUTOEXEC.CMD -----------
>[]path=;C:\UT\MTWIN
+[]SET TZ=EST
--------------------------------MTWIN /W2 AUTOEXEC.BAT AUTOEXEC.CMD
There is (currently ?) one big limitation in processing SYS and BAT files:
1. INI files have internally no order, which means it makes no difference, when Password=xxxx comes before System=Compaq or vice-versa, but in SYS and BAT files, most times you must add the LSL.COM before you can load VLM.EXE !!!!!! Currently there is NO solution to this problem...
- When using Windows 3.1x, and you maintain the SYSTEM.INI File on a network but still want to use permanent swapfiles, you can do the following:
Copy the SPART.PAR and SYSTEM.INI File to the user-Windows directory. Before you copy the it, remove the read-only attribute from SPART.PAR, (ATTRIB -r SPART.PAR from DOS). This method works well until someone changes the swapfile. For example he uses the windows who is located on the C: drive and not the one on the network, and then changes the size of the swapfile. When the user now restarts the network-windows, then he gets the info that the swapfile may be damaged. This occurs because the info in spart.par does not match the size/location of 386spart.par.
To avoid this blue-screen to be displayed you can do the following:
NOTE: When you start windows with win386.exe instead of win.com, then the swapfile is not created and the user will receive a message. So it is important to start windows via win.com.
- SETENV sets the current and the MASTER environment. The parent environment is currently not modified. I still search libraries...... in C or C++. But I think this will not be possible to implement....
Since 2.22F you can now use the O and W commands to create a BAT file, who contains a SET xxx=yyyy, and then execute this in your batch-file. Look at OUTFILE.CMD for an example.
- In OS/2 the Netware Requester must be loaded, otherwise a link to a DLL is not found.
- Look at the TODO.TXT file, so you see what it planed to be implemented.
When using MTWIN in Netware environments, then you must take care which searchmode you use. The most secure way, is to set the searchmode for MTWIN to 2. To do this you must simply run SMODE MTWIN.EXE 2 . So the searchmode is set to 2.
When you don't look at this, then it is possible that a INI (CFG) file along the current search-path is opened/deleted. I'm currently working on a solution which does not need this setting.
MTWIN is emailware, which means if you find this program useful, you should send me a email. (Or a nice postcard if you don't have access to a email system)
You can redistribute it freely, as long as you don't sell it. You have the right to distribute it with your own applications, when this is required for the installation and/or normal use of it.
The simplest way (the only automatic anyway) to get informations about new versions is to subscribe to the discussion list mentioned below. I don't send messages to individuals to inform them about new versions !!!
The new version of MTWIN will be available at my compuserve Homepage
- http://ourworld.compuserve.com/homepages/Andre_Schild
- via FTP at ftp.isbiel.ch
- Compuserve EURFORUM, NOVUSER and WUGNET (And with some delay in other forums and BBS too, but I don't upload them myself there. So it's very probable, that you will not see the latest released version.)
Please don't call me !!!
All matters of mtwin are discussed in a mailling list. You can subscribe to it, with a simple message to : maiser@novus.info.isbiel.ch with SUBSCRIBE MTWIN in the messagebody.
Don't send the subscribe, unsubscribe message directly to mtwin@novus.info.isbiel.ch !!!!
You will then receive announcements about mtwin and you can post questions there. To post a question, please send the message to mtwin@novus.info.isbiel.ch. Please don't forget to tell us, which version of mtwin you use.
For more general support of INI files, you can take a look at the WUGNET and WINUSER forums on compuserve. They will also have pointers to other usefull utilities.
Compuserve | 100034,3536 Andre Schild |
Internet | neatech@dial.eunet.ch |
WWW | http://ourworld.compuserve.com/homepages/Andre_Schild |
AT&T Mail | mhs!csmail!100034.3536 |
X400 | /c=US/ad=compuserve/pd=csmail/d.id=100034.3536 |
MCI | TO: Andre Schild EMS: COMPUSERVE/ MCI ID:281-6320 MBX: 100034,3536 |
MHS | MAIL@CSERVE {100034,3536} |
CC:Mail | Andre Schild AT NEATECH (Via Compuserve) |
Postal address | Andre Schild Pfeidstrasse 8 CH-2555 Bruegg b. Biel Switzerland |