gt: 						String deviceId = matcher.group(1);
context: /**
   * openHAB, the open Home Automation Bus.
   * Copyright (C) 2010-2013, openHAB.org <admin@openhab.org>
   *
   * See the contributors.txt file in the distribution for a
   * full listing of individual contributors.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as
   * published by the Free Software Foundation; either version 3 of the
   * License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, see <http://www.gnu.org/licenses>.
   *
   * Additional permission under GNU GPL version 3 section 7
   *
   * If you modify this Program, or any covered work, by linking or
   * combining it with Eclipse (or a modified version of that library),
   * containing parts covered by the terms of the Eclipse Public License
   * (EPL), the licensors of this Program grant you additional permission
   * to convey the resulting work.
   */
  package org.openhab.binding.urtsi.internal;
  
  import java.util.Dictionary;
  import java.util.Enumeration;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  import org.openhab.binding.urtsi.UrtsiBindingProvider;
  import org.openhab.core.binding.AbstractBinding;
  import org.openhab.core.library.types.StopMoveType;
  import org.openhab.core.library.types.UpDownType;
  import org.openhab.core.types.Command;
  import org.openhab.core.types.State;
  import org.openhab.core.types.Type;
  import org.openhab.model.item.binding.BindingConfigParseException;
  import org.osgi.service.cm.ConfigurationException;
  import org.osgi.service.cm.ManagedService;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  /**
   * Main implementation of the Somfy URTSI II Binding. This binding is
   * responsible for delegating the received commands and updates to the
   * {@link UrtsiDevice}.
   * 
   * @author Oliver Libutzki
   * @since 1.3.0
   * 
   */
  public class UrtsiBinding extends AbstractBinding<UrtsiBindingProvider>
  		implements ManagedService {
  
  	private final static Logger logger = LoggerFactory
  			.getLogger(UrtsiBinding.class);
  
  	private final static String COMMAND_UP = "U";
  	private final static String COMMAND_DOWN = "D";
  	private final static String COMMAND_STOP = "S";
  
  	private final static Pattern EXTRACT_URTSI_CONFIG_PATTERN = Pattern
  			.compile("^(.*?)\\.(port)$");
  
  	/**
  	 * Maps the device id to a URTSI device. This is needed if you use multiple
  	 * ports for multiple urtsi devices.
  	 */
  	private final Map<String, UrtsiDevice> idToDeviceMap = new HashMap<String, UrtsiDevice>();
  
  	/**
  	 * The method determines the appropriate
  	 * {@link org.openhab.core.binding.BindingProvider} and uses it to get the
  	 * corresponding URTSI device and channel. Bases on the given type a command
  	 * is send to the device.
  	 * 
  	 * @param itemName
  	 *            name of the item
  	 * @param type
  	 *            Type of the command or status update
  	 * @return Returns true, if the command has been executed successfully.
  	 *         Returns false otherwise.
  	 * @throws BindingConfigParseException 
  	 */
  	private boolean sendToUrtsi(String itemName, Type type) {
  		UrtsiBindingProvider provider = null;
  		if (!providers.isEmpty()) {
  			provider = providers.iterator().next();
  		}
  		if (provider == null) {
  			if (logger.isErrorEnabled()) {
  				logger.error("doesn't find matching binding provider [itemName={}, type={}]", itemName, type);
  			}
  			return false;
  		}
  		String urtsiDeviceId = provider.getDeviceId(itemName);
  		UrtsiDevice urtsiDevice = idToDeviceMap.get(urtsiDeviceId);
  		
  		if (urtsiDevice == null) {
  			if (logger.isErrorEnabled()) {
  				logger.error("No serial port has been configured for urtsi device id '" + urtsiDeviceId +"'");
  			}
  			return false;
  		}
  		
  		int channel = provider.getChannel(itemName);
  		
  		if (urtsiDevice != null) {
  			if (logger.isDebugEnabled()) {
  				logger.debug("Send to URTSI for item: " + itemName + "; Type: " + type);
  			}
  			String actionKey = null;
  			if (type instanceof UpDownType) {
  				switch ((UpDownType)type) {
  					case UP : 
  						actionKey = COMMAND_UP; 
  						break;
  					case 
  					DOWN : actionKey = COMMAND_DOWN; 
  					break;
  				}
  			} else if (type instanceof StopMoveType) {
  				switch ((StopMoveType)type) {
  					case STOP : 
  						actionKey = COMMAND_STOP; 
  						break;
  					default:
  						break;
  				}
  			}
  			
  
  			if (logger.isDebugEnabled()) {
  				logger.debug("Action key: " + actionKey);
  			}
  			if (actionKey != null) {
  				String channelString = String.format("%02d", channel);
  				String command = "01" + channelString + actionKey;
  				boolean executedSuccessfully = urtsiDevice.writeString(command);
  				if (!executedSuccessfully) {
  					if (logger.isErrorEnabled()) {
  						logger.error("Command has not been processed [itemName={}, command={}]", itemName, command);
  					}
  				}
  				return executedSuccessfully;
  			}
  		}
  		return false;
  	}
  
  	/**
  	 * The method delegates the received command to the URTSI device and updates
  	 * the item's state, if the command has been executed successfully.
  	 */
  	protected void internalReceiveCommand(String itemName, Command command) {
  		if (logger.isDebugEnabled()) {
  			logger.debug("Received command for " + itemName + "! Command: " + command);
  		}
  		boolean executedSuccessfully = sendToUrtsi(itemName, command);
  		if (executedSuccessfully && command instanceof State) {
  			eventPublisher.postUpdate(itemName, (State)command);
  		}
  	}
  	
  	/**
  	 * The method delegates the received state-update to the URTSI device.
  	 */
  	protected void internalReceiveUpdate(String itemName, State newState) {
  		if (logger.isDebugEnabled()) {
  			logger.debug("Received update for " + itemName + "! New state: " + newState);
  		}
  		sendToUrtsi(itemName, newState);
  	}
  	
  	/**
  	 * Parses the global configuration file.
  	 * Expected values:
  	 * urtsi.<deviceid>.port=<serialport>
  	 */
  	public void updated(Dictionary<String, ? > config)	throws ConfigurationException {
  		
  		if (config != null) {
  			Enumeration<String> keys = config.keys();
  			while (keys.hasMoreElements()) {
  				String key = keys.nextElement();
  				logger.debug("Processing key '" + key + "'");
  				// the config-key enumeration contains additional keys that we
  				// don't want to process here ...
  				if (key != "service.pid") {
  					
  					Matcher matcher = EXTRACT_URTSI_CONFIG_PATTERN.matcher(key);
  					if (!matcher.matches()) {
  						logger.debug("given config key '"
  								+ key
  								+ "' does not follow the expected pattern '<id>.port'");
  					} else {
  						matcher.reset();
  						matcher.find();
  		
  