diff --git a/tutorial/haxe/src/CalculatorHandler.hx b/tutorial/haxe/src/CalculatorHandler.hx
index ee75edd..3376fb6 100644
--- a/tutorial/haxe/src/CalculatorHandler.hx
+++ b/tutorial/haxe/src/CalculatorHandler.hx
@@ -32,70 +32,70 @@
 
 
 class CalculatorHandler implements Calculator {
-	
-	private var log = new IntMap<SharedStruct>();
-	
-	public function new() {
-	}
 
-	public function ping() : Void {
-		trace("ping()");
-	}
+    private var log = new IntMap<SharedStruct>();
 
-	
-	public function add( num1 : haxe.Int32, num2 : haxe.Int32) : haxe.Int32 {
-		trace('add( $num1, $num2)');
-		return num1 + num2;
-	}
+    public function new() {
+    }
 
-	public function calculate( logid : haxe.Int32, work : Work) : haxe.Int32  {
-		trace('calculate( $logid, '+work.op+","+work.num1+","+work.num2+")");
-		
-		var val : haxe.Int32 = 0;
-		switch (work.op)
-		{
-			case Operation.ADD:
-				val = work.num1 + work.num2;
+    public function ping() : Void {
+        trace("ping()");
+    }
 
-			case Operation.SUBTRACT:
-				val = work.num1 - work.num2;
 
-			case Operation.MULTIPLY:
-				val = work.num1 * work.num2;
+    public function add( num1 : haxe.Int32, num2 : haxe.Int32) : haxe.Int32 {
+        trace('add( $num1, $num2)');
+        return num1 + num2;
+    }
 
-			case Operation.DIVIDE:
-				if (work.num2 == 0)
-				{
-					var io = new InvalidOperation();
-					io.what = work.op;
-					io.why = "Cannot divide by 0";
-					throw io;
-				}
-				val = Std.int( work.num1 / work.num2);
+    public function calculate( logid : haxe.Int32, work : Work) : haxe.Int32  {
+        trace('calculate( $logid, '+work.op+","+work.num1+","+work.num2+")");
 
-			default:
-				var io = new InvalidOperation();
-				io.what = work.op;
-				io.why = "Unknown operation";
-				throw io;
-		}
+        var val : haxe.Int32 = 0;
+        switch (work.op)
+        {
+            case Operation.ADD:
+                val = work.num1 + work.num2;
 
-		var entry = new SharedStruct();
-		entry.key = logid;
-		entry.value = '$val';
-		log.set(logid, entry);
+            case Operation.SUBTRACT:
+                val = work.num1 - work.num2;
 
-		return val;
-	}
+            case Operation.MULTIPLY:
+                val = work.num1 * work.num2;
 
-	public function getStruct( key : haxe.Int32) : SharedStruct {
-		trace('getStruct($key)');
-		return log.get(key);
-	}
+            case Operation.DIVIDE:
+                if (work.num2 == 0)
+                {
+                    var io = new InvalidOperation();
+                    io.what = work.op;
+                    io.why = "Cannot divide by 0";
+                    throw io;
+                }
+                val = Std.int( work.num1 / work.num2);
 
-	// oneway method,  no args
-	public function zip() : Void {
-		trace("zip()");
-	}
+            default:
+                var io = new InvalidOperation();
+                io.what = work.op;
+                io.why = "Unknown operation";
+                throw io;
+        }
+
+        var entry = new SharedStruct();
+        entry.key = logid;
+        entry.value = '$val';
+        log.set(logid, entry);
+
+        return val;
+    }
+
+    public function getStruct( key : haxe.Int32) : SharedStruct {
+        trace('getStruct($key)');
+        return log.get(key);
+    }
+
+    // oneway method,  no args
+    public function zip() : Void {
+        trace("zip()");
+    }
 
 }
diff --git a/tutorial/haxe/src/Main.hx b/tutorial/haxe/src/Main.hx
index 41d8945..d4ba054 100644
--- a/tutorial/haxe/src/Main.hx
+++ b/tutorial/haxe/src/Main.hx
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
- 
+
 package;
 
 import org.apache.thrift.*;
@@ -30,296 +30,297 @@
 
 
 enum Prot {
-	binary;
-	json;
+    binary;
+    json;
 }
 
 enum Trns {
-	socket;
-	http;
+    socket;
+    http;
 }
 
 class Main {
-	
-	private static var server : Bool = false;
-	private static var framed : Bool = false;
-	private static var buffered : Bool = false;
-	private static var prot : Prot = binary;
-	private static var trns : Trns = socket;
-	
-	private static var targetHost : String = "localhost";
-	private static var targetPort : Int = 9090;
-	
-	static function main() {
-		#if ! (flash || js)
-		try {
-  			ParseArgs();
-		} catch (e : String) {
-			trace(e);
-			trace(GetHelp());
-			return;
-		}
-		#end
 
-		try {
-			if (server)
-				RunServer();
-			else 
-				RunClient();
-		} catch (e : String) {
-			trace(e);
-		}
+    private static var server : Bool = false;
+    private static var framed : Bool = false;
+    private static var buffered : Bool = false;
+    private static var prot : Prot = binary;
+    private static var trns : Trns = socket;
 
-		trace("Completed.");
+    private static var targetHost : String = "localhost";
+    private static var targetPort : Int = 9090;
+
+    static function main() {
+        #if ! (flash || js)
+        try {
+              ParseArgs();
+        } catch (e : String) {
+            trace(e);
+            trace(GetHelp());
+            return;
+        }
+        #end
+
+        try {
+            if (server)
+                RunServer();
+            else
+                RunClient();
+        } catch (e : String) {
+            trace(e);
+        }
+
+        trace("Completed.");
     }
 
-	
-	#if ! (flash || js)
-		
-	private static function GetHelp() : String {
-		return Sys.executablePath()+"  modus  trnsOption  transport  protocol\n"
-		+"Options:\n"
-		+"  modus:       client, server   (default: client)\n"
-		+"  trnsOption:  framed, buffered (default: none)\n"
-		+"  transport:   socket, http     (default: socket)\n"
-		+"  protocol:    binary, json     (default: binary)\n"
-		+"\n"
-		+"All arguments are optional.\n";
-	}
-	
 
-	private static function ParseArgs() : Void {
-		var step = 0;
-		for (arg in Sys.args()) {
-			
-			// server|client
-			switch(step) {
-			case 0:
-				++step;
-				if ( arg == "client") 
-					server = false;
-				else if ( arg == "server") 
-					server = true;
-				else
-					throw "First argument must be 'server' or 'client'";
-					
-			case 1:					
-				if ( arg == "framed") {
-					framed = true;
-				} else if ( arg == "buffered") {
-					buffered = true;
-				} else if ( arg == "socket") {
-					trns = socket;
-					++step;
-				} else if ( arg == "http") {
-					trns = http;
-					++step;
-				} else {
-					throw "Unknown transport "+arg;
-				}					
+    #if ! (flash || js)
 
-			case 2:					
-				if ( arg == "binary") {
-					prot = binary;
-					++step;
-				} else if ( arg == "json") {
-					prot = json;
-					++step;
-				} else {
-					throw "Unknown protocol "+arg;
-				}					
+    private static function GetHelp() : String {
+        return Sys.executablePath()+"  modus  trnsOption  transport  protocol\n"
+        +"Options:\n"
+        +"  modus:       client, server   (default: client)\n"
+        +"  trnsOption:  framed, buffered (default: none)\n"
+        +"  transport:   socket, http     (default: socket)\n"
+        +"  protocol:    binary, json     (default: binary)\n"
+        +"\n"
+        +"All arguments are optional.\n";
+    }
 
-			default:
-				throw "Unexpected argument "+arg;
-			}
 
-			if ( framed && buffered)
-			{
-				trace("WN: framed supersedes buffered");
-			}
+    private static function ParseArgs() : Void {
+        var step = 0;
+        for (arg in Sys.args()) {
 
-		}
-	}
+            // server|client
+            switch(step) {
+            case 0:
+                ++step;
+                if ( arg == "client")
+                    server = false;
+                else if ( arg == "server")
+                    server = true;
+                else
+                    throw "First argument must be 'server' or 'client'";
 
-	#end
-	
-	private static function ClientSetup() : Calculator {
-	 	trace("Client configuration:");
+            case 1:
+                if ( arg == "framed") {
+                    framed = true;
+                } else if ( arg == "buffered") {
+                    buffered = true;
+                } else if ( arg == "socket") {
+                    trns = socket;
+                    ++step;
+                } else if ( arg == "http") {
+                    trns = http;
+                    ++step;
+                } else {
+                    throw "Unknown transport "+arg;
+                }
 
-		// endpoint transport
-		var transport : TTransport;
-		switch(trns)
-		{
-		case socket:
-		 	trace('- socket transport $targetHost:$targetPort');
-			transport = new TSocket( targetHost, targetPort);
+            case 2:
+                if ( arg == "binary") {
+                    prot = binary;
+                    ++step;
+                } else if ( arg == "json") {
+                    prot = json;
+                    ++step;
+                } else {
+                    throw "Unknown protocol "+arg;
+                }
+
+            default:
+                throw "Unexpected argument "+arg;
+            }
+
+            if ( framed && buffered)
+            {
+                trace("WN: framed supersedes buffered");
+            }
+
+        }
+    }
+
+    #end
+
+    private static function ClientSetup() : Calculator {
+         trace("Client configuration:");
+
+        // endpoint transport
+        var transport : TTransport;
+        switch(trns)
+        {
+        case socket:
+             trace('- socket transport $targetHost:$targetPort');
+            transport = new TSocket( targetHost, targetPort);
         case http:
-		 	trace('- HTTP transport $targetHost');
-			transport = new THttpClient( targetHost);
-		default:
-			throw "Unhandled transport";
-		}
+             trace('- HTTP transport $targetHost');
+            transport = new THttpClient( targetHost);
+        default:
+            throw "Unhandled transport";
+        }
 
-		
-		// optinal layered transport
-		if ( framed) {
-		 	trace("- framed transport");
-			transport = new TFramedTransport(transport);
-		} else if ( buffered) {
-		 	trace("- buffered transport");
-			throw "TBufferedTransport not implemented yet";
-			//transport = new TBufferedTransport(transport);
-		}
 
-		
-		// protocol
-		var protocol : TProtocol;
-		switch(prot)
-		{
-		case binary:
-		 	trace("- binary protocol");
-		 	protocol = new TBinaryProtocol( transport);
+        // optinal layered transport
+        if ( framed) {
+             trace("- framed transport");
+            transport = new TFramedTransport(transport);
+        } else if ( buffered) {
+             trace("- buffered transport");
+            throw "TBufferedTransport not implemented yet";
+            //transport = new TBufferedTransport(transport);
+        }
+
+
+        // protocol
+        var protocol : TProtocol;
+        switch(prot)
+        {
+        case binary:
+             trace("- binary protocol");
+             protocol = new TBinaryProtocol( transport);
         case json:
-		 	trace("- JSON protocol");
-		 	protocol = new TJSONProtocol( transport);
-		default:
-			throw "Unhandled protocol";
-		}
-
-		
-		// put everything together
-		transport.open();	
-		return new CalculatorImpl(protocol,protocol);
-	}
-	
-	
-	private static function RunClient() : Void {
-		var client = ClientSetup();
-
-		try {
-		  	client.ping();
-			trace("ping() successful");
-		} catch(error : TException) { 
-			trace('ping() failed: $error'); 
-		} catch(error : Dynamic) { 
-			trace('ping() failed: $error'); 
-		}
-
-		try {
-			var sum = client.add( 1, 1); 
-			trace('1+1=$sum');
-		} catch(error : TException) { 
-			trace('add() failed: $error'); 
-		} catch(error : Dynamic) { 
-			trace('add() failed: $error'); 
-		}
+             trace("- JSON protocol");
+             protocol = new TJSONProtocol( transport);
+        default:
+            throw "Unhandled protocol";
+        }
 
 
-		var work = new tutorial.Work();
-		work.op = tutorial.Operation.DIVIDE;
-		work.num1 = 1;
-		work.num2 = 0;
-		try {
-			var quotient = client.calculate( 1, work); 
-			trace('Whoa we can divide by 0! Result = $quotient'); 
-		} catch(error : TException) { 
-			trace('calculate() failed: $error'); 
-		} catch(error : Dynamic) { 
-			trace('calculate() failed: $error'); 
-		}
-
-		work.op = tutorial.Operation.SUBTRACT;
-		work.num1 = 15;
-		work.num2 = 10;
-		try {
-			var diff = client.calculate( 1, work);
-			trace('15-10=$diff');
-		} catch(error : TException) { 
-			trace('calculate() failed: $error'); 
-		} catch(error : Dynamic) { 
-			trace('calculate() failed: $error'); 
-		}
+        // put everything together
+        transport.open();
+        return new CalculatorImpl(protocol,protocol);
+    }
 
 
-		try {
-			var log : SharedStruct = client.getStruct( 1);
-			var logval = log.value;
-			trace('Check log: $logval');
-		} catch(error : TException) { 
-			trace('getStruct() failed: $error'); 
-		} catch(error : Dynamic) { 
-			trace('getStruct() failed: $error'); 
-		}
-	}
-	
-	
-	private static function ServerSetup() : TServer {
-	 	trace("Server configuration:");
+    private static function RunClient() : Void {
+        var client = ClientSetup();
 
-		// endpoint transport
-		var transport : TServerTransport = null;
-		switch(trns)
-		{
-		case socket:
-			#if (flash || js)
-			throw 'current platform does not support socket servers';
-			#else
-		 	trace('- socket transport port $targetPort');
-			transport = new TServerSocket( targetPort);
-			#end
+        try {
+              client.ping();
+            trace("ping() successful");
+        } catch(error : TException) {
+            trace('ping() failed: $error');
+        } catch(error : Dynamic) {
+            trace('ping() failed: $error');
+        }
+
+        try {
+            var sum = client.add( 1, 1);
+            trace('1+1=$sum');
+        } catch(error : TException) {
+            trace('add() failed: $error');
+        } catch(error : Dynamic) {
+            trace('add() failed: $error');
+        }
+
+
+        var work = new tutorial.Work();
+        work.op = tutorial.Operation.DIVIDE;
+        work.num1 = 1;
+        work.num2 = 0;
+        try {
+            var quotient = client.calculate( 1, work);
+            trace('Whoa we can divide by 0! Result = $quotient');
+        } catch(error : TException) {
+            trace('calculate() failed: $error');
+        } catch(error : Dynamic) {
+            trace('calculate() failed: $error');
+        }
+
+        work.op = tutorial.Operation.SUBTRACT;
+        work.num1 = 15;
+        work.num2 = 10;
+        try {
+            var diff = client.calculate( 1, work);
+            trace('15-10=$diff');
+        } catch(error : TException) {
+            trace('calculate() failed: $error');
+        } catch(error : Dynamic) {
+            trace('calculate() failed: $error');
+        }
+
+
+        try {
+            var log : SharedStruct = client.getStruct( 1);
+            var logval = log.value;
+            trace('Check log: $logval');
+        } catch(error : TException) {
+            trace('getStruct() failed: $error');
+        } catch(error : Dynamic) {
+            trace('getStruct() failed: $error');
+        }
+    }
+
+
+    private static function ServerSetup() : TServer {
+         trace("Server configuration:");
+
+        // endpoint transport
+        var transport : TServerTransport = null;
+        switch(trns)
+        {
+        case socket:
+            #if (flash || js)
+            throw 'current platform does not support socket servers';
+            #else
+             trace('- socket transport port $targetPort');
+            transport = new TServerSocket( targetPort);
+            #end
         case http:
-			throw "HTTP server not implemented yet";
-		 	//trace("- http transport");
-		 	//transport = new THttpClient( targetHost);
-		default:
-			throw "Unhandled transport";
-		}
-		
-		// optional: layered transport
-		var transfactory : TTransportFactory = null;
-		if ( framed) {
-		 	trace("- framed transport");
-			transfactory = new TFramedTransportFactory();
-		} else if ( buffered) {
-		 	trace("- buffered transport");
-			throw "TBufferedTransport not implemented yet";
-			//transfactory = new TBufferedTransportFactory();
-		}
-		
-		// protocol
-		var protfactory : TProtocolFactory = null;
-		switch(prot)
-		{
-		case binary:
-		 	trace("- binary protocol");
-		 	protfactory = new TBinaryProtocolFactory();
-        case json:
-			trace("- JSON protocol");
-		 	protfactory = new TJSONProtocolFactory();
-		default:
-			throw "Unhandled protocol";
-		}
-		
-		var handler = new CalculatorHandler();
-		var processor = new CalculatorProcessor(handler);
-		var server = new TSimpleServer( processor, transport, transfactory, protfactory);
-		return server;
-	}
-	
-	
-	private static function RunServer() : Void {
-		try
-		{
-			var server = ServerSetup();
+            throw "HTTP server not implemented yet";
+             //trace("- http transport");
+             //transport = new THttpClient( targetHost);
+        default:
+            throw "Unhandled transport";
+        }
 
-			trace("\nStarting the server...");
-			server.Serve();
-		}
-		catch( e : Dynamic)
-		{
-			trace('RunServer() failed: $e');
-		}
-		trace("done.");
-	}
-	
+        // optional: layered transport
+        var transfactory : TTransportFactory = null;
+        if ( framed) {
+             trace("- framed transport");
+            transfactory = new TFramedTransportFactory();
+        } else if ( buffered) {
+             trace("- buffered transport");
+            throw "TBufferedTransport not implemented yet";
+            //transfactory = new TBufferedTransportFactory();
+        }
+
+        // protocol
+        var protfactory : TProtocolFactory = null;
+        switch(prot)
+        {
+        case binary:
+             trace("- binary protocol");
+             protfactory = new TBinaryProtocolFactory();
+        case json:
+            trace("- JSON protocol");
+             protfactory = new TJSONProtocolFactory();
+        default:
+            throw "Unhandled protocol";
+        }
+
+        var handler = new CalculatorHandler();
+        var processor = new CalculatorProcessor(handler);
+        var server = new TSimpleServer( processor, transport, transfactory, protfactory);
+        return server;
+    }
+
+
+    private static function RunServer() : Void {
+        try
+        {
+            var server = ServerSetup();
+
+            trace("\nStarting the server...");
+            server.Serve();
+        }
+        catch( e : Dynamic)
+        {
+            trace('RunServer() failed: $e');
+        }
+        trace("done.");
+    }
+
 }
+ 
\ No newline at end of file
