// Path: src/main/java/com/sketchy/hardware/Direction.java
// public enum Direction {
// 	BACKWARD(-1), NONE(0), FORWARD(1);
// 
// 	private int value;
// 	
//     private Direction(int value) {
//     	this.value = value;
//     }
// 
//     public static Direction fromValue(int value){
//     	if (value==0) {
//     		return NONE;
//     	} else if (value>0){
//     		return FORWARD;
//     	} else {
//     		return BACKWARD;
//     	}
//     }
//     
//     
//     public int getValue() {
// 		return value;
// 	}
//     
// }
// 
// Path: src/main/java/com/sketchy/hardware/HardwareController.java
// public abstract class HardwareController {
// 
// 	//protected HardwareControllerProperties properties = null; 
// 	// This is to ensure that the Constructor in subclasses is created
// 	protected HardwareController(HardwareControllerProperties properties){}
// 	
// 	private static HardwareController _this = null;
// 	
// 	public abstract HardwareControllerProperties getProperties();
// 
// 	public synchronized static HardwareController getInstance() throws Exception {
// 		if (_this==null){
// 			throw new Exception("Instance not created. Use newInstance(HardwareControllerProperties properties) first!");
// 		}
// 		return _this;
// 	}
// 		
// 	public synchronized static HardwareController newInstance(HardwareControllerProperties properties) throws Exception {
// 		Class<? extends HardwareController> controllerClass = properties.getImplementationClass();
// 		
// 		try{
// 			if (_this!=null){
// 				// existing instance
// 				_this.shutDown();
// 				_this=null;
// 			}
// 			
// 			Constructor<? extends HardwareController> constructor = controllerClass.getConstructor(new Class[]{properties.getClass()});
// 			_this=constructor.newInstance(new Object[]{properties});
// 		} catch (IllegalAccessException e){
// 			throw new Exception("Error Getting HardwareController Instance from Class '" + controllerClass.getName() + "'! " + e.toString());
// 		} catch (InstantiationException e){
// 			throw new Exception("Error Getting HardwareController Instance from Class '" + controllerClass.getName() + "'!" + e.toString());
// 		} catch (InvocationTargetException e){
// 			throw new Exception(e.getTargetException().getMessage());
// 		}
// 		
// 		return _this;
// 	}
// 
// 	public abstract void penUp();
// 
// 	public abstract void penDown();
// 		
// 	// Based on Bresenham's line algorithm
// 	public void moveMotors(int leftSteps, int rightSteps, long delayInMicroSeconds) throws Exception {
// 		// Just return if no steps occurring
// 		if ((leftSteps==0) && (rightSteps==0)) return;
// 		
// 		boolean swapSteps=Math.abs(rightSteps) > Math.abs(leftSteps);
// 	    if (swapSteps){
// 	    	int temp=leftSteps;
// 	    	leftSteps=rightSteps;
// 	    	rightSteps=temp;
// 	    }
// 
// 	    Direction leftMotorDirection =  Direction.fromValue(leftSteps);
// 	    Direction rightMotorDirection = Direction.fromValue(rightSteps);
// 		
// 	    leftSteps = Math.abs(leftSteps);  
// 	    rightSteps = Math.abs(rightSteps);  
// 	    
//         int error=leftSteps/2;
//         for (int steps=0;steps<leftSteps;steps++){
// 	    	Direction stepRight=Direction.NONE;
//         	error-=rightSteps;
//         	if(error<0){
//         		stepRight=rightMotorDirection;
//         		error+=leftSteps;
//         	}
//         	if (swapSteps){
//         		stepMotors(stepRight, leftMotorDirection, delayInMicroSeconds);
//         	} else {
//         		stepMotors(leftMotorDirection, stepRight, delayInMicroSeconds);
//         	}
// 	    }
// 	}
// 	
// 	public abstract void stepMotors(Direction leftMotorDirection, Direction rightMotorDirection, long delayInMicroSeconds);
// 	
// 	public abstract void enableMotors();
// 	
// 	public abstract void disableMotors();
// 
// 	public abstract void shutDown();
// 		
// 	@SuppressWarnings("unchecked")
// 	public static Map<String, String> getHardwareControllerClassMap() throws Exception { 
// 		List<Class<?>> classes = ClassScanner.getClassesForPackage("com.sketchy.hardware.impl", MetaDataObject.class);
// 		Map<String, String> classMap = new LinkedHashMap<String, String>();
// 		for (Class<?> clazz:classes){
// 			Class<HardwareControllerProperties> hardwareControllerClass = (Class<HardwareControllerProperties>) clazz;
// 			Class<HardwareController> implementationClass = (Class<HardwareController>) hardwareControllerClass.newInstance().getImplementationClass();
// 			classMap.put(implementationClass.getName(), clazz.getName());
// 		}
// 		return classMap;
// 	}
// 	
// }


import java.io.File;
import org.apache.commons.io.FileUtils;
import com.pi4j.wiringpi.Gpio;
import com.sketchy.hardware.Direction;
import com.sketchy.hardware.HardwareController;
	}
	
	@Override
	public synchronized void enableMotors() {
		Gpio.digitalWrite(properties.getLeftMotorEnablePinNumber(), false);
		Gpio.digitalWrite(properties.getRightMotorEnablePinNumber(), false);
	}

	@Override
	public synchronized void disableMotors() {
		Gpio.digitalWrite(properties.getLeftMotorEnablePinNumber(), true);
		Gpio.digitalWrite(properties.getRightMotorEnablePinNumber(), true);		
	}

	@Override
	public synchronized void shutDown() {
		System.out.println("RaspberryPIServoController: shutDown.");
		tearDownPins();
	}

	private synchronized static String buildServoCommand(int pinNumber, int value){
		if (sbuf.length()>0) sbuf.delete(0, sbuf.length()-1);
		sbuf.append("s ").append(Integer.toString(pinNumber)).append(" ").append(Integer.toString(value)).append(System.lineSeparator());
		return sbuf.toString();
	}


	private synchronized void setupPins() {
		int retryCount=0;
		while(true){
// Path: src/main/java/com/sketchy/hardware/Direction.java
// public enum Direction {
// 	BACKWARD(-1), NONE(0), FORWARD(1);
// 
// 	private int value;
// 	
//     private Direction(int value) {
//     	this.value = value;
//     }
// 
//     public static Direction fromValue(int value){
//     	if (value==0) {
//     		return NONE;
//     	} else if (value>0){
//     		return FORWARD;
//     	} else {
//     		return BACKWARD;
//     	}
//     }
//     
//     
//     public int getValue() {
// 		return value;
// 	}
//     
// }
// 
// Path: src/main/java/com/sketchy/hardware/HardwareController.java
// public abstract class HardwareController {
// 
// 	//protected HardwareControllerProperties properties = null; 
// 	// This is to ensure that the Constructor in subclasses is created
// 	protected HardwareController(HardwareControllerProperties properties){}
// 	
// 	private static HardwareController _this = null;
// 	
// 	public abstract HardwareControllerProperties getProperties();
// 
// 	public synchronized static HardwareController getInstance() throws Exception {
// 		if (_this==null){
// 			throw new Exception("Instance not created. Use newInstance(HardwareControllerProperties properties) first!");
// 		}
// 		return _this;
// 	}
// 		
// 	public synchronized static HardwareController newInstance(HardwareControllerProperties properties) throws Exception {
// 		Class<? extends HardwareController> controllerClass = properties.getImplementationClass();
// 		
// 		try{
// 			if (_this!=null){
// 				// existing instance
// 				_this.shutDown();
// 				_this=null;
// 			}
// 			
// 			Constructor<? extends HardwareController> constructor = controllerClass.getConstructor(new Class[]{properties.getClass()});
// 			_this=constructor.newInstance(new Object[]{properties});
// 		} catch (IllegalAccessException e){
// 			throw new Exception("Error Getting HardwareController Instance from Class '" + controllerClass.getName() + "'! " + e.toString());
// 		} catch (InstantiationException e){
// 			throw new Exception("Error Getting HardwareController Instance from Class '" + controllerClass.getName() + "'!" + e.toString());
// 		} catch (InvocationTargetException e){
// 			throw new Exception(e.getTargetException().getMessage());
// 		}
// 		
// 		return _this;
// 	}
// 
// 	public abstract void penUp();
// 
// 	public abstract void penDown();
// 		
// 	// Based on Bresenham's line algorithm
// 	public void moveMotors(int leftSteps, int rightSteps, long delayInMicroSeconds) throws Exception {
// 		// Just return if no steps occurring
// 		if ((leftSteps==0) && (rightSteps==0)) return;
// 		
// 		boolean swapSteps=Math.abs(rightSteps) > Math.abs(leftSteps);
// 	    if (swapSteps){
// 	    	int temp=leftSteps;
// 	    	leftSteps=rightSteps;
// 	    	rightSteps=temp;
// 	    }
// 
// 	    Direction leftMotorDirection =  Direction.fromValue(leftSteps);
// 	    Direction rightMotorDirection = Direction.fromValue(rightSteps);
// 		
// 	    leftSteps = Math.abs(leftSteps);  
// 	    rightSteps = Math.abs(rightSteps);  
// 	    
//         int error=leftSteps/2;
//         for (int steps=0;steps<leftSteps;steps++){
// 	    	Direction stepRight=Direction.NONE;
//         	error-=rightSteps;
//         	if(error<0){
//         		stepRight=rightMotorDirection;
//         		error+=leftSteps;
//         	}
//         	if (swapSteps){
//         		stepMotors(stepRight, leftMotorDirection, delayInMicroSeconds);
//         	} else {
//         		stepMotors(leftMotorDirection, stepRight, delayInMicroSeconds);
//         	}
// 	    }
// 	}
// 	
// 	public abstract void stepMotors(Direction leftMotorDirection, Direction rightMotorDirection, long delayInMicroSeconds);
// 	
// 	public abstract void enableMotors();
// 	
// 	public abstract void disableMotors();
// 
// 	public abstract void shutDown();
// 		
// 	@SuppressWarnings("unchecked")
// 	public static Map<String, String> getHardwareControllerClassMap() throws Exception { 
// 		List<Class<?>> classes = ClassScanner.getClassesForPackage("com.sketchy.hardware.impl", MetaDataObject.class);
// 		Map<String, String> classMap = new LinkedHashMap<String, String>();
// 		for (Class<?> clazz:classes){
// 			Class<HardwareControllerProperties> hardwareControllerClass = (Class<HardwareControllerProperties>) clazz;
// 			Class<HardwareController> implementationClass = (Class<HardwareController>) hardwareControllerClass.newInstance().getImplementationClass();
// 			classMap.put(implementationClass.getName(), clazz.getName());
// 		}
// 		return classMap;
// 	}
// 	
// }


// Path: src/main/java/com/sketchy/hardware/impl/RaspberryPIServoController.java
import java.io.File;
import org.apache.commons.io.FileUtils;
import com.pi4j.wiringpi.Gpio;
import com.sketchy.hardware.Direction;
import com.sketchy.hardware.HardwareController;

	}
	
	@Override
	public synchronized void enableMotors() {
		Gpio.digitalWrite(properties.getLeftMotorEnablePinNumber(), false);
		Gpio.digitalWrite(properties.getRightMotorEnablePinNumber(), false);
	}

	@Override
	public synchronized void disableMotors() {
		Gpio.digitalWrite(properties.getLeftMotorEnablePinNumber(), true);
		Gpio.digitalWrite(properties.getRightMotorEnablePinNumber(), true);		
	}

	@Override
	public synchronized void shutDown() {
		System.out.println("RaspberryPIServoController: shutDown.");
		tearDownPins();
	}

	private synchronized static String buildServoCommand(int pinNumber, int value){
		if (sbuf.length()>0) sbuf.delete(0, sbuf.length()-1);
		sbuf.append("s ").append(Integer.toString(pinNumber)).append(" ").append(Integer.toString(value)).append(System.lineSeparator());
		return sbuf.toString();
	}


	private synchronized void setupPins() {
		int retryCount=0;
		while(true){
			try{