diff --git a/.gitignore b/.gitignore
index cb613eefeb3240c0cdab593f7c9fd11bee34e806..503baa332de9a413450931f60e60305525a9e978 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,7 @@ doc/*.html
 *x86_64-unknown-*
 sip_autoconf.h
 os-auto.mak
+cc-auto.mak
 build.mak
 config.log
 config.status
@@ -69,6 +70,13 @@ config_auto.h
 # Cscope/Ctags files
 cscope.*
 tags
+TAGS.LST
+ID
 
 # IDE stuffs
 nbproject
+
+# JNI generated files
+*_wrap.cpp
+*_wrap.h
+*_loader.c
diff --git a/astylerc b/astylerc
index 5fe7ea2a692f3923a99b1d7502341a6f3ec5874e..7f14310574b90b9d41b3065853175a0edf06b0b6 100644
--- a/astylerc
+++ b/astylerc
@@ -13,6 +13,7 @@ break-blocks        # Pad empty lines around header blocks (e.g. 'if', 'while'..
 brackets=linux
 unpad-paren         # Remove unwanted space around parentheses
 pad-header          # Insert space padding after paren headers only (e.g. 'if', 'for', 'while'...)
+pad-oper            # Insert space padding around operator
 formatted           # only display files that have changed
 recursive           # recursively enter subdirs
 suffix=none         # don't create backup files (that's what version control is for)
diff --git a/daemon/.cproject b/daemon/.cproject
deleted file mode 100644
index 2e2c63ac1528664da909fe2924f7590dab4705c2..0000000000000000000000000000000000000000
--- a/daemon/.cproject
+++ /dev/null
@@ -1,940 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?fileVersion 4.0.0?>
-
-<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
-	<storageModule moduleId="org.eclipse.cdt.core.settings">
-		<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1334434668">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1334434668" moduleId="org.eclipse.cdt.core.settings" name="Debug">
-				<externalSettings/>
-				<extensions>
-					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="daemon" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1334434668" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
-					<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1334434668." name="/" resourcePath="">
-						<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1440064034" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
-							<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.1326164352" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
-							<builder buildPath="${workspace_loc:/daemon}" id="cdt.managedbuild.target.gnu.builder.exe.debug.943929430" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="-1" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
-							<tool id="cdt.managedbuild.tool.gnu.archiver.base.346381185" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.27143558" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
-								<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.921724511" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
-								<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1752614994" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.548320150" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.8935091" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
-								<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1442755176" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
-								<option id="gnu.c.compiler.exe.debug.option.debugging.level.768478086" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
-								<option id="gnu.c.compiler.option.include.paths.672698944" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath"/>
-								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1769752022" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1740382896" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1001572120" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2023620584" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-								</inputType>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1753020190" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
-								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.384585975" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-							</tool>
-						</toolChain>
-					</folderInfo>
-					<sourceEntries>
-						<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
-					</sourceEntries>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="scannerConfiguration">
-				<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-				<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="makefileGenerator">
-						<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1334434668;cdt.managedbuild.config.gnu.exe.debug.1334434668.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.8935091;cdt.managedbuild.tool.gnu.c.compiler.input.1769752022">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.418162094;cdt.managedbuild.config.gnu.exe.release.418162094.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1870258177;cdt.managedbuild.tool.gnu.c.compiler.input.186132729">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.418162094;cdt.managedbuild.config.gnu.exe.release.418162094.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.270168324;cdt.managedbuild.tool.gnu.cpp.compiler.input.758787020">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1334434668;cdt.managedbuild.config.gnu.exe.debug.1334434668.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.27143558;cdt.managedbuild.tool.gnu.cpp.compiler.input.548320150">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
-			<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
-		</cconfiguration>
-		<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.418162094">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.418162094" moduleId="org.eclipse.cdt.core.settings" name="Release">
-				<externalSettings/>
-				<extensions>
-					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="daemon" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.418162094" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
-					<folderInfo id="cdt.managedbuild.config.gnu.exe.release.418162094." name="/" resourcePath="">
-						<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.1224261522" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
-							<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1551176649" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
-							<builder buildPath="${workspace_loc:/daemon}" id="cdt.managedbuild.target.gnu.builder.exe.release.821405347" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="-1" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
-							<tool id="cdt.managedbuild.tool.gnu.archiver.base.808688542" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.270168324" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
-								<option id="gnu.cpp.compiler.exe.release.option.optimization.level.324641683" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
-								<option id="gnu.cpp.compiler.exe.release.option.debugging.level.1322686559" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.758787020" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.1870258177" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
-								<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1967167078" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/>
-								<option id="gnu.c.compiler.exe.release.option.debugging.level.1326539031" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
-								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.186132729" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.1339934122" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1247653269" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2024163167" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-								</inputType>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.779475213" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
-								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1675601061" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-							</tool>
-						</toolChain>
-					</folderInfo>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="scannerConfiguration">
-				<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-				<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="makefileGenerator">
-						<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1334434668;cdt.managedbuild.config.gnu.exe.debug.1334434668.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.8935091;cdt.managedbuild.tool.gnu.c.compiler.input.1769752022">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.418162094;cdt.managedbuild.config.gnu.exe.release.418162094.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1870258177;cdt.managedbuild.tool.gnu.c.compiler.input.186132729">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.418162094;cdt.managedbuild.config.gnu.exe.release.418162094.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.270168324;cdt.managedbuild.tool.gnu.cpp.compiler.input.758787020">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1334434668;cdt.managedbuild.config.gnu.exe.debug.1334434668.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.27143558;cdt.managedbuild.tool.gnu.cpp.compiler.input.548320150">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
-			<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
-		</cconfiguration>
-	</storageModule>
-	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-		<project id="daemon.cdt.managedbuild.target.gnu.exe.246189308" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
-	</storageModule>
-</cproject>
diff --git a/daemon/.gitignore b/daemon/.gitignore
index f3ac37f26d20da7cd5004287d783a6895bc8c4d5..7c6793afafcff5ba58756c1737fbeb25708376a5 100644
--- a/daemon/.gitignore
+++ b/daemon/.gitignore
@@ -1,7 +1,8 @@
 aclocal.m4
+build-aux
 
 configure
-src/dbus/org.sflphone.SFLphone.service
+src/client/dbus/org.sflphone.SFLphone.service
 src/sflphoned
 
 # Ignore sub-modules stuff
diff --git a/daemon/.project b/daemon/.project
deleted file mode 100644
index 8bfaab5ca3eeaed4fd1838c33d91c57c652511f7..0000000000000000000000000000000000000000
--- a/daemon/.project
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>daemon</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-			<triggers>clean,full,incremental,</triggers>
-			<arguments>
-				<dictionary>
-					<key>?name?</key>
-					<value></value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.append_environment</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
-					<value>all</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildArguments</key>
-					<value>-j</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildCommand</key>
-					<value>make</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildLocation</key>
-					<value>${workspace_loc:/daemon}</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
-					<value>clean</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.contents</key>
-					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
-					<value>false</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
-					<value>all</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.stopOnError</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
-					<value>true</value>
-				</dictionary>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.cdt.core.cnature</nature>
-		<nature>org.eclipse.cdt.core.ccnature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
-	</natures>
-</projectDescription>
diff --git a/daemon/configure-android.sh b/daemon/configure-android.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b61a06ba54cc57b6166c49b263fc253e765d35d2
--- /dev/null
+++ b/daemon/configure-android.sh
@@ -0,0 +1 @@
+./configure --without-dbus --without-alsa --without-pulse --without-tls --without-iax2  --without-zrtp --without-sdes --without-speexdsp --without-speex
diff --git a/daemon/configure.ac b/daemon/configure.ac
index a16e9bdaf70b9b55ec7937de0e676355a05dd881..6ffd8c2ef185a0c4d5d02d7d546400b447563bff 100644
--- a/daemon/configure.ac
+++ b/daemon/configure.ac
@@ -35,6 +35,9 @@ LT_INIT
 dnl Define C++ as default language
 AC_LANG(C++)
 
+dnl Check for C++11 support
+AX_CXX_COMPILE_STDCXX_11
+
 dnl Check for header files
 AC_FUNC_ALLOCA
 AC_HEADER_STDC
@@ -74,7 +77,16 @@ PKG_CHECK_MODULES(LIBCRYPTO, libcrypto >= ${LIBCRYPTO_MIN_VERSION}, HAVE_LIBCRYP
 
 dnl Check for alsa development package - name: libasound2-dev
 ALSA_MIN_VERSION=1.0
-PKG_CHECK_MODULES(ALSA, alsa >= ${ALSA_MIN_VERSION},, AC_MSG_ERROR([Missing alsa development package: libasound2-dev or alsa-lib-devel]))
+AC_ARG_WITH([alsa],
+	[ AS_HELP_STRING([--without-alsa], [disable support for alsa]) ],
+	[],
+	[with_alsa=yes])
+AS_IF([test "x$with_alsa" = "xyes"], [
+       PKG_CHECK_MODULES(ALSA, alsa >= ${ALSA_MIN_VERSION},, AC_MSG_ERROR([Missing alsa development files]))
+	]);
+
+AC_DEFINE_UNQUOTED([HAVE_ALSA], `if test "x$with_alsa" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have alsa])
+AM_CONDITIONAL(BUILD_ALSA, test "x$with_alsa" = "xyes")
 
 
 dnl Check for pulseaudio development package - name: libpulse-dev
@@ -85,15 +97,18 @@ AC_ARG_WITH([pulse],
     [with_pulse=yes])
 
 AS_IF([test "x$with_pulse" = "xyes"], [
-    PKG_CHECK_MODULES(PULSEAUDIO, libpulse >= ${LIBPULSE_MIN_VERSION},, AC_MSG_ERROR([Missing pulseaudio development package: libpulse-dev]))
+       PKG_CHECK_MODULES(PULSEAUDIO, libpulse >= ${LIBPULSE_MIN_VERSION},, AC_MSG_ERROR([Missing pulseaudio development files]))
       ]);
 
 AC_DEFINE_UNQUOTED([HAVE_PULSE], `if test "x$with_pulse" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have pulseaudio])
-AM_CONDITIONAL(BUILD_PULSE, test "x$with_pulse" = "xyes" )
+AM_CONDITIONAL(BUILD_PULSE, test "x$with_pulse" = "xyes")
 
 dnl Check for the samplerate development package - name: libsamplerate0-dev
 LIBSAMPLERATE_MIN_VERSION=0.1.2
-PKG_CHECK_MODULES(SAMPLERATE, samplerate >= ${LIBSAMPLERATE_MIN_VERSION},, AC_MSG_ERROR([Missing libsamplerate development package: libsamplerate0-dev]))
+PKG_CHECK_MODULES(SAMPLERATE, samplerate >= ${LIBSAMPLERATE_MIN_VERSION},, AC_MSG_ERROR([Missing libsamplerate development files]))
+
+dnl Check for the sndfile development package - name: libsndfile-dev
+PKG_CHECK_MODULES(SNDFILE, sndfile,, AC_MSG_ERROR([Missing sndfile development files]))
 
 dnl Coverage is default-disabled
 AC_ARG_ENABLE([coverage], AS_HELP_STRING([--enable-coverage], [Enable coverage]))
@@ -112,22 +127,22 @@ AS_IF([test "x$enable_video" = "xyes"],
 
         dnl The libav versions correspond to the last libav release: 0.7
         dnl Check for libavcodec development package - name: libavcodec-dev
-        PKG_CHECK_MODULES(LIBAVCODEC, libavcodec >= 53.5.0,, AC_MSG_ERROR([Missing libavcodec package: libavcodec-dev]))
+        PKG_CHECK_MODULES(LIBAVCODEC, libavcodec >= 53.5.0,, AC_MSG_ERROR([Missing libavcodec development files]))
         LIBAVCODEC_CFLAGS="${LIBAVCODEC_CFLAGS} -D__STDC_CONSTANT_MACROS"
 
         dnl Check for libavformat development package - name: libavformat-dev
-        PKG_CHECK_MODULES(LIBAVFORMAT, libavformat >= 53.2.0,, AC_MSG_ERROR([Missing libavformat package: libavformat-dev]))
+        PKG_CHECK_MODULES(LIBAVFORMAT, libavformat >= 53.2.0,, AC_MSG_ERROR([Missing libavformat development files]))
 
         dnl Check for libswscale development package - name: libswcale-dev
-        PKG_CHECK_MODULES(LIBSWSCALE, libswscale >= 1.1.0,, AC_MSG_ERROR([Missing libswscale package: libswscale-dev]))
+        PKG_CHECK_MODULES(LIBSWSCALE, libswscale >= 1.1.0,, AC_MSG_ERROR([Missing libswscale development files]))
 
         dnl Check for libavdevice development package - name: libavdevice-dev
-        PKG_CHECK_MODULES(LIBAVDEVICE, libavdevice >= 53.0.0,, AC_MSG_ERROR([Missing libavdevice package: libavdevice-dev]))
+        PKG_CHECK_MODULES(LIBAVDEVICE, libavdevice >= 53.0.0,, AC_MSG_ERROR([Missing libavdevice development files]))
 
         dnl Check for libavutil development package - name: libavutil-dev
-        PKG_CHECK_MODULES(LIBAVUTIL, libavutil >= 51.7.0,, AC_MSG_ERROR([Missing libavutil package: libavutil-dev]))
+        PKG_CHECK_MODULES(LIBAVUTIL, libavutil >= 51.7.0,, AC_MSG_ERROR([Missing libavutil development files]))
 
-        PKG_CHECK_MODULES(UDEV, libudev,, AC_MSG_ERROR([Missing libudev package: libudev-dev]))
+        PKG_CHECK_MODULES(UDEV, libudev,, AC_MSG_ERROR([Missing libudev development files]))
     ],
     [AM_CONDITIONAL(SFL_VIDEO, false)]);
 
@@ -135,12 +150,12 @@ AS_IF([test "x$enable_video" = "xyes"],
 LIBCCGNU2_MIN_VERSION=1.3.1
 PKG_CHECK_MODULES([CCGNU2], [commoncpp] >= ${LIBCCGNU2_MIN_VERSION}, AC_DEFINE_UNQUOTED([COMMONCPP_PREFIX], [1], [Use commoncpp include prefix]), [
         PKG_CHECK_MODULES([CCGNU2], [libccgnu2] >= ${LIBCCGNU2_MIN_VERSION}, AC_DEFINE_UNQUOTED([CCPP_PREFIX], [1], [Use cc++ include prefix]),
-            AC_MSG_ERROR([Missing common cpp development package: libcommoncpp2-dev]))
+        AC_MSG_ERROR([Missing commoncpp development files]))
         ])
 
 LIBCCRTP_MIN_VERSION=1.3.0
 PKG_CHECK_MODULES([CCRTP], [libccrtp] >= ${LIBCCRTP_MIN_VERSION},, [
-        PKG_CHECK_MODULES([CCRTP], [libccrtp1] >= ${LIBCCRTP_MIN_VERSION},, AC_MSG_ERROR([Missing ccrtp development package: libccrtp-dev]))
+                   PKG_CHECK_MODULES([CCRTP], [libccrtp1] >= ${LIBCCRTP_MIN_VERSION},, AC_MSG_ERROR([Missing ccrtp development files]))
         ])
 
 
@@ -152,7 +167,7 @@ AC_ARG_WITH([tls],
     [],
     [with_tls=yes])
 AS_IF([test "x$with_tls" = "xyes"], [
-    PKG_CHECK_MODULES([libssl], libssl,, AC_MSG_ERROR([Missing ssl development package: libssl-dev]))
+       PKG_CHECK_MODULES([libssl], libssl,, AC_MSG_ERROR([Missing ssl development files]))
     ]);
 
 AC_DEFINE_UNQUOTED([HAVE_TLS], `if test "x$with_tls" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have tls support])
@@ -168,22 +183,23 @@ AC_ARG_WITH([zrtp],
     [],
     [with_zrtp=yes])
 AS_IF([test "x$with_zrtp" = "xyes"], [
-    PKG_CHECK_MODULES([ZRTPCPP], libzrtpcpp >= ${LIBZRTPCPP_MIN_VERSION},, AC_MSG_ERROR([Missing zrtp development package: libzrtpcpp-dev]))
+       PKG_CHECK_MODULES([ZRTPCPP], libzrtpcpp >= ${LIBZRTPCPP_MIN_VERSION},, AC_MSG_ERROR([Missing zrtp development files]))
     ]);
 
 AC_DEFINE_UNQUOTED([HAVE_ZRTP], `if test "x$with_zrtp" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have zrtp support])
 AM_CONDITIONAL(BUILD_ZRTP, test "x$with_zrtp" = "xyes" )
 
+# DBUSCPP
+dnl Check for dbuscpp, the C++ bindings for D-Bus
+AC_ARG_WITH([dbus],
+    [AS_HELP_STRING([--without-dbus], [disable support for dbus])],
+    [],
+    [with_dbus=yes])
+AS_IF([test "x$with_dbus" = "xyes"], [
+       PKG_CHECK_MODULES(DBUSCPP, dbus-c++-1,, AC_MSG_WARN([Missing dbus development files]))
+    ]);
 
-# DBUS
-# required dependency(ies): libdbus-c++
-dnl DBus-C++ detection
-dnl pkg-config doesn't like 0.6.0-pre1 version number, it assumes that it is
-dnl more recent than (unreleased) 0.6.0
-DBUS_CPP_REQUIRED_VERSION=0.6.0-pre1
-PKG_CHECK_MODULES(DBUSCPP, dbus-c++-1,,
-AC_MSG_ERROR([You need the DBus-c++ libraries (version $DBUS_CPP_REQUIRED_VERSION or better)]))
-
+AC_DEFINE_UNQUOTED([HAVE_DBUS], `if test "x$with_dbus" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have dbus support])
 
 # Instant Messaging
 # required dependency(ies): libxpat
@@ -193,7 +209,7 @@ AC_ARG_WITH([instant_messaging],
     [with_instant_messaging=yes])
 AS_IF([test "x$with_instant_messaging" = "xyes"], [
     AX_LIB_EXPAT([1.95.0])
-    AS_IF([test "$HAVE_EXPAT" != "yes"], [AC_MSG_ERROR([libexpat could not be found, which is required to build this package.])], [])
+    AS_IF([test "$HAVE_EXPAT" != "yes"], [AC_MSG_ERROR([Missing libexpat development files])], [])
     ]);
 
 AC_DEFINE_UNQUOTED([HAVE_INSTANT_MESSAGING], `if test "x$with_instant_messaging" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have instant messaging support])
@@ -253,7 +269,7 @@ AC_ARG_WITH([speex],
         [with_speex=yes])
 
 AS_IF([test "x$with_speex" != xno],
-        [AC_CHECK_HEADER([speex/speex.h], , AC_MSG_FAILURE([Unable to find the libspeex headers (you may need to install the dev package).  You may use --without-speex to compile without speex codec support.]))]
+      [AC_CHECK_HEADER([speex/speex.h], , AC_MSG_FAILURE([Missing speex development files. You may use --without-speex to compile without speex codec support.]))]
         [AC_CHECK_LIB([speex], [speex_decode_int],
         [],
         [AC_MSG_FAILURE([libspeex link test failed.   You may use --without-speex to compile without speex codec support.])])
@@ -273,7 +289,7 @@ AC_ARG_WITH([speexdsp],
     [with_speexdsp=yes])
 
 AS_IF([test "x$with_speexdsp" != xno],
-    AC_CHECK_HEADER([speex/speex_preprocess.h], , AC_MSG_FAILURE([Unable to find the libspeexdsp headers (you may need to install the libspeexdsp-dev package) used for Noise Suppression and Automatic Gain Control.]))
+      AC_CHECK_HEADER([speex/speex_preprocess.h], , AC_MSG_FAILURE([Missing libspeexdsp development files used for Noise Suppression and Automatic Gain Control.]))
     AC_SEARCH_LIBS([speex_preprocess_run], [speexdsp], [], [AC_MSG_ERROR([Unable to find speexdsp development files])])
     )
 
@@ -365,7 +381,8 @@ AC_CONFIG_FILES([Makefile \
                  src/audio/sound/Makefile \
                  src/audio/codecs/Makefile \
                  src/config/Makefile \
-                 src/dbus/Makefile \
+                 src/client/Makefile \
+                 src/client/dbus/Makefile \
                  src/hooks/Makefile \
                  src/history/Makefile \
                  src/video/Makefile \
diff --git a/daemon/globals.mak b/daemon/globals.mak
index e291f920cf6ce08b2a1198932752316a0373cec8..05d413ee18244a0b5aa4117832510b23d73c8237 100644
--- a/daemon/globals.mak
+++ b/daemon/globals.mak
@@ -25,6 +25,12 @@ else
 SPEEXCODEC=
 endif
 
+if BUILD_OPUS
+OPUSCODEC=-DHAVE_OPUS
+else
+OPUSCODEC=
+endif
+
 if BUILD_GSM
 GSMCODEC=-DHAVE_GSM_CODEC
 else
@@ -46,8 +52,9 @@ AM_CPPFLAGS = \
 	-DCODECS_DIR=\""$(sflcodecdir)"\" \
 	-DPLUGINS_DIR=\""$(sflplugindir)"\" \
 	-DENABLE_TRACE \
-         $(SPEEXCODEC) \
-         $(GSMCODEC)
+	$(SPEEXCODEC) \
+	$(GSMCODEC) \
+	$(OPUSCODEC)
 
 
 indent:
diff --git a/daemon/libs/iax2/iax.c b/daemon/libs/iax2/iax.c
index 013879ac725a4789e82621366c8669ec6be6cd90..41b2bc73bdf82090a2d1efa2a995fa32ffb1902b 100644
--- a/daemon/libs/iax2/iax.c
+++ b/daemon/libs/iax2/iax.c
@@ -564,7 +564,7 @@ static int calc_timestamp(struct iax_session *session, unsigned int ts, struct a
 	   special cases.  */
 	if (ts)
 	{
-		if ( f && session )
+		if ( f )
 			session->lastsent = ts;
 		return ts;
 	}
@@ -842,12 +842,14 @@ static int iax_reliable_xmit(struct iax_frame *f)
 		if (!fc->data || !fc->datalen) {
 			IAXERROR "No frame data?");
 			DEBU(G "No frame data?\n");
+            free(fc);
 			return -1;
 		} else {
 			fc->data = (char *)malloc(fc->datalen);
 			if (!fc->data) {
 				DEBU(G "Out of memory\n");
 				IAXERROR "Out of memory\n");
+				free(fc);
 				return -1;
 			}
 			memcpy(fc->data, f->data, f->datalen);
@@ -876,7 +878,7 @@ int iax_init(int preferredportno)
 
 	if (iax_recvfrom == (iax_recvfrom_t)recvfrom)
 	{
-		struct sockaddr_in sin;
+		struct sockaddr_in sin = {};
 		socklen_t sinlen;
 		int flags;
 		int bufsize = 256 * 1024;
@@ -1198,7 +1200,7 @@ static int iax_send(struct iax_session *pvt, struct ast_frame *f, unsigned int t
 			res = iax_xmit_frame(fr);
 		}
 	}
-	if( !now && fr!=NULL )
+	if( !now )
 		iax_frame_free( fr );
 	return res;
 }
@@ -1989,6 +1991,7 @@ void iax_pref_codec_del(struct iax_session *session, unsigned int format)
 	char remove = which_bit(format) + diff;
 
 	strncpy(old, session->codec_order, sizeof(old));
+    old[sizeof(old) - 1] = '\0';
 	session->codec_order_len = 0;
 
 	for (x = 0;  x < (int) strlen(old);  x++) {
@@ -2644,6 +2647,7 @@ static struct iax_event *iax_header_to_event(struct iax_session *session, struct
 					strncpy(session->codec_order,
 							e->ies.codec_prefs,
 							sizeof(session->codec_order));
+					session->codec_order[sizeof(session->codec_order) - 1] = '\0';
 					session->codec_order_len =
 						(int)strlen(session->codec_order);
 				}
@@ -3128,7 +3132,7 @@ struct iax_event *iax_net_process(unsigned char *buf, int len, struct sockaddr_i
 
 static struct iax_sched *iax_get_sched(struct timeval tv)
 {
-	struct iax_sched *cur, *prev=NULL;
+	struct iax_sched *cur;
 	cur = schedq;
 	/* Check the event schedule first. */
 	while(cur) {
@@ -3136,11 +3140,7 @@ static struct iax_sched *iax_get_sched(struct timeval tv)
 		    ((tv.tv_sec == cur->when.tv_sec) &&
 			(tv.tv_usec >= cur->when.tv_usec))) {
 				/* Take it out of the event queue */
-				if (prev) {
-					prev->next = cur->next;
-				} else {
-					schedq = cur->next;
-				}
+				schedq = cur->next;
 				return cur;
 		}
 		cur = cur->next;
diff --git a/daemon/libs/iax2/iax2-parser.c b/daemon/libs/iax2/iax2-parser.c
index 958380a4094c650f41daa889f050535427c7111a..0f538d8dca2c4991ca583eeb81c4736d07546ae0 100644
--- a/daemon/libs/iax2/iax2-parser.c
+++ b/daemon/libs/iax2/iax2-parser.c
@@ -369,7 +369,7 @@ void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, s
 		/* Don't mess with mini-frames */
 		return;
 	}
-	if (fh->type > (int)sizeof(frames)/(int)sizeof(char *)) {
+	if (fh->type >= (int)sizeof(frames)/(int)sizeof(char *)) {
 		snprintf(class2, (int)sizeof(class2), "(%d?)", fh->type);
 		clas = class2;
 	} else {
@@ -386,7 +386,7 @@ void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, s
 			subclass = iaxs[(int)fh->csub];
 		}
 	} else if (fh->type == AST_FRAME_CONTROL) {
-		if (fh->csub > (int)sizeof(cmds)/(int)sizeof(char *)) {
+		if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(char *)) {
 			snprintf(subclass2, (int)sizeof(subclass2), "(%d?)", fh->csub);
 			subclass = subclass2;
 		} else {
diff --git a/daemon/libs/iax2/jitterbuf.c b/daemon/libs/iax2/jitterbuf.c
index 0d450240c15e8db21ed4923743b6b9468de458c9..6e74c3fc40761724fc6c5e239a8fc965ed7a2146 100644
--- a/daemon/libs/iax2/jitterbuf.c
+++ b/daemon/libs/iax2/jitterbuf.c
@@ -237,8 +237,10 @@ static void history_calc_maxbuf(jitterbuf *jb)
 			for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
 				/* found where it fits */
 				if (toins > jb->hist_maxbuf[j]) {
-					/* move over */
-					memmove(jb->hist_maxbuf + j + 1, jb->hist_maxbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_maxbuf[0]));
+					/* move over if there's space */
+                    const size_t slide = (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_maxbuf[0]);
+					if (j < (JB_HISTORY_MAXBUF_SZ - 1))
+						memmove(jb->hist_maxbuf + j + 1, jb->hist_maxbuf + j, slide);
 					/* insert */
 					jb->hist_maxbuf[j] = toins;
 
@@ -254,8 +256,10 @@ static void history_calc_maxbuf(jitterbuf *jb)
 			for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
 				/* found where it fits */
 				if (toins < jb->hist_minbuf[j]) {
-					/* move over */
-					memmove(jb->hist_minbuf + j + 1, jb->hist_minbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_minbuf[0]));
+					/* move over if there's space */
+					const size_t slide = (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_minbuf[0]);
+					if (j < (JB_HISTORY_MAXBUF_SZ - 1))
+						memmove(jb->hist_minbuf + j + 1, jb->hist_minbuf + j, slide);
 					/* insert */
 					jb->hist_minbuf[j] = toins;
 
@@ -263,18 +267,6 @@ static void history_calc_maxbuf(jitterbuf *jb)
 				}
 			}
 		}
-
-		if (0) {
-			int k;
-			fprintf(stderr, "toins = %ld\n", toins);
-			fprintf(stderr, "maxbuf =");
-			for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
-				fprintf(stderr, "%ld ", jb->hist_maxbuf[k]);
-			fprintf(stderr, "\nminbuf =");
-			for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
-				fprintf(stderr, "%ld ", jb->hist_minbuf[k]);
-			fprintf(stderr, "\n");
-		}
 	}
 
 	jb->hist_maxbuf_valid = 1;
diff --git a/daemon/libs/iax2/md5.c b/daemon/libs/iax2/md5.c
index 656601f98b3094293a1b0c84f1015c41eea07301..3830a61fda83e0cd2bbb1e93f21e279896da1c50 100644
--- a/daemon/libs/iax2/md5.c
+++ b/daemon/libs/iax2/md5.c
@@ -116,7 +116,7 @@ void IAX_MD5Update(struct IAX_MD5Context *ctx, uint8_t const *buf, unsigned int
 	}
 	memcpy(p, buf, t);
 	IAX_byteReverse(ctx->in, 16);
-	IAX_MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+	IAX_MD5Transform(ctx->buf, ctx->in_32);
 	buf += t;
 	len -= t;
     }
@@ -171,13 +171,13 @@ void IAX_MD5Final(uint8_t digest[16], struct IAX_MD5Context *ctx)
     IAX_byteReverse(ctx->in, 14);
 
     /* Append length in bits and transform */
-    ((uint32_t *) ctx->in)[14] = ctx->bits[0];
-    ((uint32_t *) ctx->in)[15] = ctx->bits[1];
+    ctx->in_32[14] = ctx->bits[0];
+    ctx->in_32[15] = ctx->bits[1];
 
-    IAX_MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+    IAX_MD5Transform(ctx->buf, ctx->in_32);
     IAX_byteReverse((uint8_t *) ctx->buf, 4);
     memcpy(digest, ctx->buf, 16);
-    memset(ctx, 0, sizeof(ctx));	/* In case it's sensitive */
+    memset(ctx, 0, sizeof(*ctx));	/* In case it's sensitive */
 }
 
 #ifndef ASM_MD5
diff --git a/daemon/libs/iax2/md5.h b/daemon/libs/iax2/md5.h
index b3ad37a9b36532268cc9f3e62d909963c70e8e01..f54b68bfb27de352d4143230a5cbffddd175606b 100644
--- a/daemon/libs/iax2/md5.h
+++ b/daemon/libs/iax2/md5.h
@@ -11,7 +11,10 @@ typedef unsigned char uint8_t;
 struct IAX_MD5Context {
 	uint32_t buf[4];
 	uint32_t bits[2];
-	uint8_t in[64];
+	union {
+	    uint8_t in[64];
+	    uint32_t in_32[16];
+	};
 };
 
 void IAX_MD5Init(struct IAX_MD5Context *context);
diff --git a/daemon/m4/ax_cxx_compile_stdcxx_11.m4 b/daemon/m4/ax_cxx_compile_stdcxx_11.m4
new file mode 100644
index 0000000000000000000000000000000000000000..af37acdb5ca2c9f76bffdc1a12edfb862282af56
--- /dev/null
+++ b/daemon/m4/ax_cxx_compile_stdcxx_11.m4
@@ -0,0 +1,133 @@
+# ============================================================================
+#  http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+#   AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
+#
+# DESCRIPTION
+#
+#   Check for baseline language coverage in the compiler for the C++11
+#   standard; if necessary, add switches to CXXFLAGS to enable support.
+#
+#   The first argument, if specified, indicates whether you insist on an
+#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+#   -std=c++11).  If neither is specified, you get whatever works, with
+#   preference for an extended mode.
+#
+#   The second argument, if specified 'mandatory' or if left unspecified,
+#   indicates that baseline C++11 support is required and that the macro
+#   should error out if no mode with that support is found.  If specified
+#   'optional', then configuration proceeds regardless, after defining
+#   HAVE_CXX11 if and only if a supporting mode is found.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 3
+
+m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
+  template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+    typedef check<check<bool>> right_angle_brackets;
+
+    int a;
+    decltype(a) b;
+
+    typedef check<int> check_type;
+    check_type c;
+    check_type&& cr = static_cast<check_type&&>(c);
+
+    auto d = a;
+])
+
+AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
+  m4_if([$1], [], [],
+        [$1], [ext], [],
+        [$1], [noext], [],
+        [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
+  m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
+        [$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
+        [$2], [optional], [ax_cxx_compile_cxx11_required=false],
+        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
+  AC_LANG_PUSH([C++])dnl
+  ac_success=no
+  AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
+  ax_cv_cxx_compile_cxx11,
+  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+    [ax_cv_cxx_compile_cxx11=yes],
+    [ax_cv_cxx_compile_cxx11=no])])
+  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+    ac_success=yes
+  fi
+
+  m4_if([$1], [noext], [], [dnl
+  if test x$ac_success = xno; then
+    for switch in -std=gnu++11 -std=gnu++0x; do
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+                     $cachevar,
+        [ac_save_CXXFLAGS="$CXXFLAGS"
+         CXXFLAGS="$CXXFLAGS $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXXFLAGS="$ac_save_CXXFLAGS"])
+      if eval test x\$$cachevar = xyes; then
+        CXXFLAGS="$CXXFLAGS $switch"
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+
+  m4_if([$1], [ext], [], [dnl
+  if test x$ac_success = xno; then
+    for switch in -std=c++11 -std=c++0x; do
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+                     $cachevar,
+        [ac_save_CXXFLAGS="$CXXFLAGS"
+         CXXFLAGS="$CXXFLAGS $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXXFLAGS="$ac_save_CXXFLAGS"])
+      if eval test x\$$cachevar = xyes; then
+        CXXFLAGS="$CXXFLAGS $switch"
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+  AC_LANG_POP([C++])
+  if test x$ax_cxx_compile_cxx11_required = xtrue; then
+    if test x$ac_success = xno; then
+      AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
+    fi
+  else
+    if test x$ac_success = xno; then
+      HAVE_CXX11=0
+      AC_MSG_NOTICE([No compiler with C++11 support was found])
+    else
+      HAVE_CXX11=1
+      AC_DEFINE(HAVE_CXX11,1,
+                [define if the compiler supports basic C++11 syntax])
+    fi
+
+    AC_SUBST(HAVE_CXX11)
+  fi
+])
diff --git a/daemon/src/Makefile.am b/daemon/src/Makefile.am
index 83e3652fb4bc8c2930a3201edc8c35bcb94f3f76..656204f6f044b570363da84b9fc72661bdcc46ce 100644
--- a/daemon/src/Makefile.am
+++ b/daemon/src/Makefile.am
@@ -24,7 +24,7 @@ if USE_NETWORKMANAGER
 NETWORKMANAGER=-DUSE_NETWORKMANAGER
 endif
 
-SUBDIRS = dbus audio config hooks history sip $(IAX_SUBDIR) $(INSTANT_MESSAGING_SUBDIR) $(SFL_VIDEO_SUBDIR)
+SUBDIRS = client audio config hooks history sip $(IAX_SUBDIR) $(INSTANT_MESSAGING_SUBDIR) $(SFL_VIDEO_SUBDIR)
 
 sflphoned_SOURCES = main.cpp
 
@@ -41,7 +41,7 @@ libsflphone_la_LIBADD = \
 	$(IAX_LIB) \
 	./sip/libsiplink.la \
 	./audio/libaudio.la \
-	./dbus/libdbus.la \
+	./client/dbus/libclient.la \
 	./config/libconfig.la \
 	./hooks/libhooks.la \
 	./history/libhistory.la $(SFL_VIDEO_LIB) $(IM_LIB)
@@ -55,6 +55,7 @@ libsflphone_la_LDFLAGS = \
 		@ALSA_LIBS@ \
 		@PULSEAUDIO_LIBS@ \
 		@SAMPLERATE_LIBS@ \
+		@SNDFILE_LIBS@ \
 		@libssl_LIBS@ \
 		@UUID_LIBS@ \
 		@DBUSCPP_LIBS@
@@ -69,14 +70,14 @@ libsflphone_la_CFLAGS = \
 		@PULSEAUDIO_CFLAGS@ \
 		@SAMPLERATE_CFLAGS@ \
 		@libssl_CFLAGS@ \
-		@UUID_CFLAGS@
+		@UUID_CFLAGS@ \
+		@DBUSCPP_CFLAGS@
 
 libsflphone_la_SOURCES = conference.cpp \
 		voiplink.cpp \
 		preferences.cpp \
 		managerimpl.cpp \
 		manager.cpp \
-		managerimpl_registration.cpp \
 		eventthread.cpp \
 		call.cpp \
 		account.cpp \
diff --git a/daemon/src/account.cpp b/daemon/src/account.cpp
index ce497ce18a134a5cff20ef6acd6ebfed92799a13..363d975e3ad4770ec6d137a23bdf018dc668fecb 100644
--- a/daemon/src/account.cpp
+++ b/daemon/src/account.cpp
@@ -42,7 +42,8 @@
 
 #include "logger.h"
 #include "manager.h"
-#include "dbus/configurationmanager.h"
+
+#include "client/configurationmanager.h"
 
 const char * const Account::AUDIO_CODECS_KEY =      "audioCodecs";  // 0/9/110/111/112/
 const char * const Account::VIDEO_CODECS_KEY =      "videoCodecs";
@@ -63,6 +64,8 @@ const char * const Account::HOSTNAME_KEY =          "hostname";
 const char * const Account::ACCOUNT_ENABLE_KEY =    "enable";
 const char * const Account::ACCOUNT_AUTOANSWER_KEY =    "autoAnswer";
 const char * const Account::MAILBOX_KEY =           "mailbox";
+const char * const Account::DEFAULT_USER_AGENT =    "SFLphone/" PACKAGE_VERSION;
+const char * const Account::USER_AGENT_KEY =        "useragent";
 
 using std::map;
 using std::string;
@@ -83,7 +86,7 @@ Account::Account(const string &accountID) :
     , ringtonePath_("/usr/share/sflphone/ringtones/konga.ul")
     , ringtoneEnabled_(true)
     , displayName_("")
-    , userAgent_("SFLphone")
+    , userAgent_(DEFAULT_USER_AGENT)
     , mailBox_()
 {
     // Initialize the codec order, used when creating a new account
@@ -97,9 +100,8 @@ void Account::setRegistrationState(const RegistrationState &state)
 {
     if (state != registrationState_) {
         registrationState_ = state;
-
         // Notify the client
-        ConfigurationManager *c(Manager::instance().getDbusManager()->getConfigurationManager());
+        ConfigurationManager *c(Manager::instance().getClient()->getConfigurationManager());
         c->registrationStateChanged(accountID_, registrationState_);
     }
 }
@@ -157,8 +159,8 @@ namespace {
         }
 
         // check that it's in the list of valid codecs and that it has all the required fields
-        for (vector<map<string, string> >::const_iterator i = defaults.begin(); i != defaults.end(); ++i) {
-            const map<string, string>::const_iterator defaultName = i->find(Account::VIDEO_CODEC_NAME);
+        for (const auto &i : defaults) {
+            const auto defaultName = i.find(Account::VIDEO_CODEC_NAME);
             if (defaultName->second == name->second) {
                 return isFieldValid(codec, Account::VIDEO_CODEC_BITRATE, isPositiveInteger)
                     and isFieldValid(codec, Account::VIDEO_CODEC_ENABLED, isBoolean);
@@ -170,16 +172,15 @@ namespace {
 
     bool isCodecListValid(const vector<map<string, string> > &list)
     {
-        const vector<map<string, string> > defaults(libav_utils::getDefaultCodecs());
+        const auto defaults(libav_utils::getDefaultCodecs());
         if (list.size() != defaults.size()) {
             ERROR("New codec list has a different length than the list of supported codecs");
             return false;
         }
 
         // make sure that all codecs are present
-        for (vector<map<string, string> >::const_iterator i = list.begin();
-             i != list.end(); ++i) {
-            if (not isCodecValid(*i, defaults))
+        for (const auto &i : list) {
+            if (not isCodecValid(i, defaults))
                 return false;
         }
         return true;
@@ -235,8 +236,8 @@ void Account::setActiveAudioCodecs(const vector<string> &list)
 
     // list contains the ordered payload of active codecs picked by the user for this account
     // we used the codec vector to save the order.
-    for (vector<string>::const_iterator iter = list.begin(); iter != list.end(); ++iter) {
-        int payload = std::atoi(iter->c_str());
+    for (const auto &item : list) {
+        int payload = std::atoi(item.c_str());
         audioCodecList_.push_back(payload);
     }
 
diff --git a/daemon/src/account.h b/daemon/src/account.h
index b2aabf09c98aa22751ee53c39705dadffbe68c07..fc8877cda7295729a939d232c8d5c2628d1ed141 100644
--- a/daemon/src/account.h
+++ b/daemon/src/account.h
@@ -222,6 +222,8 @@ class Account : public Serializable {
         static const char * const ACCOUNT_ENABLE_KEY;
         static const char * const ACCOUNT_AUTOANSWER_KEY;
         static const char * const MAILBOX_KEY;
+        static const char * const USER_AGENT_KEY;
+        static const char * const DEFAULT_USER_AGENT;
 
         static std::string mapStateNumberToString(RegistrationState state);
 
diff --git a/daemon/src/audio/Makefile.am b/daemon/src/audio/Makefile.am
index d59969e1642150047251d94cc97c14f4541d9a49..d5b25ec8f08db40584eb292b84736e30126a3e8a 100644
--- a/daemon/src/audio/Makefile.am
+++ b/daemon/src/audio/Makefile.am
@@ -2,7 +2,11 @@ include $(top_srcdir)/globals.mak
 
 noinst_LTLIBRARIES = libaudio.la
 
-SUBDIRS = codecs audiortp sound alsa
+SUBDIRS = codecs audiortp sound
+
+if BUILD_ALSA
+SUBDIRS += alsa
+endif
 
 if BUILD_PULSE
 SUBDIRS += pulseaudio
@@ -14,6 +18,7 @@ SFL_SPEEXDSP_HEAD=noisesuppress.h
 endif
 
 libaudio_la_SOURCES = \
+		audiobuffer.cpp \
 		audioloop.cpp \
 		ringbuffer.cpp \
 		mainbuffer.cpp \
@@ -28,6 +33,7 @@ libaudio_la_SOURCES = \
 		dcblocker.cpp
 
 noinst_HEADERS = \
+		audiobuffer.h \
 		audioloop.h \
 		ringbuffer.h \
 		mainbuffer.h \
@@ -44,9 +50,12 @@ noinst_HEADERS = \
 libaudio_la_LIBADD = \
 	./audiortp/libaudiortp.la \
 	./codecs/libcodecdescriptor.la \
-	./alsa/libalsalayer.la \
 	./sound/libsound.la
 
 if BUILD_PULSE
 libaudio_la_LIBADD += ./pulseaudio/libpulselayer.la
 endif
+
+if BUILD_ALSA
+libaudio_la_LIBADD += ./alsa/libalsalayer.la
+endif
diff --git a/daemon/src/audio/alsa/Makefile.am b/daemon/src/audio/alsa/Makefile.am
index 4ca799e54638c2e2bc293990e86e9a491a66641d..ce6f2ad100218ae5b055857f4c10810239bf42dc 100644
--- a/daemon/src/audio/alsa/Makefile.am
+++ b/daemon/src/audio/alsa/Makefile.am
@@ -1,8 +1,11 @@
 include $(top_srcdir)/globals.mak
 
+if BUILD_ALSA
+
 noinst_LTLIBRARIES = libalsalayer.la
 
 libalsalayer_la_SOURCES = alsalayer.cpp
 
 noinst_HEADERS = alsalayer.h
 
+endif
diff --git a/daemon/src/audio/alsa/alsalayer.cpp b/daemon/src/audio/alsa/alsalayer.cpp
index f34e72a9a65c03e2eee24ab526921d38a79ae7a2..4fb286fd7319c0d2e0e539786af998c139028612 100644
--- a/daemon/src/audio/alsa/alsalayer.cpp
+++ b/daemon/src/audio/alsa/alsalayer.cpp
@@ -37,12 +37,12 @@
 #include "logger.h"
 #include "manager.h"
 #include "noncopyable.h"
-#include "dbus/configurationmanager.h"
+#include "client/configurationmanager.h"
 #include <ctime>
 
 #define SFL_ALSA_PERIOD_SIZE 160
 #define SFL_ALSA_NB_PERIOD 8
-#define SFL_ALSA_BUFFER_SIZE SFL_ALSA_PERIOD_SIZE*SFL_ALSA_NB_PERIOD
+#define SFL_ALSA_BUFFER_SIZE SFL_ALSA_PERIOD_SIZE * SFL_ALSA_NB_PERIOD
 
 class AlsaThread {
     public:
@@ -74,6 +74,7 @@ bool AlsaThread::isRunning() const
 AlsaThread::~AlsaThread()
 {
     running_ = false;
+
     if (thread_)
         pthread_join(thread_, NULL);
 }
@@ -112,18 +113,18 @@ void AlsaThread::initAudioLayer(void)
         alsa_->is_capture_open_ = alsa_->openDevice(&alsa_->captureHandle_, pcmc, SND_PCM_STREAM_CAPTURE);
 
         if (not alsa_->is_capture_open_)
-            Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_CAPTURE_DEVICE);
+            Manager::instance().getClient()->getConfigurationManager()->errorAlert(ALSA_CAPTURE_DEVICE);
     }
 
     if (not alsa_->is_playback_open_) {
         alsa_->is_playback_open_ = alsa_->openDevice(&alsa_->playbackHandle_, pcmp, SND_PCM_STREAM_PLAYBACK);
 
         if (not alsa_->is_playback_open_)
-            Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_PLAYBACK_DEVICE);
+            Manager::instance().getClient()->getConfigurationManager()->errorAlert(ALSA_PLAYBACK_DEVICE);
 
         if (alsa_->getIndexPlayback() != alsa_->getIndexRingtone())
             if (!alsa_->openDevice(&alsa_->ringtoneHandle_, pcmr, SND_PCM_STREAM_PLAYBACK))
-                Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_PLAYBACK_DEVICE);
+                Manager::instance().getClient()->getConfigurationManager()->errorAlert(ALSA_PLAYBACK_DEVICE);
     }
 
     alsa_->prepareCaptureStream();
@@ -149,7 +150,6 @@ void AlsaThread::run()
     }
 }
 
-// Constructor
 AlsaLayer::AlsaLayer(const AudioPreference &pref)
     : indexIn_(pref.getAlsaCardin())
     , indexOut_(pref.getAlsaCardout())
@@ -172,7 +172,6 @@ AlsaLayer::AlsaLayer(const AudioPreference &pref)
     setPlaybackGain(pref.getVolumespkr());
 }
 
-// Destructor
 AlsaLayer::~AlsaLayer()
 {
     isStarted_ = false;
@@ -198,7 +197,7 @@ bool AlsaLayer::openDevice(snd_pcm_t **pcm, const std::string &dev, snd_pcm_stre
 
     if (err < 0) {
         ERROR("Alsa: couldn't open device %s : %s",  dev.c_str(),
-               snd_strerror(err));
+              snd_strerror(err));
         return false;
     }
 
@@ -248,10 +247,6 @@ AlsaLayer::stopStream()
     flushMain();
 }
 
-//////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////   ALSA PRIVATE FUNCTIONS   ////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////////
-
 /*
  * GCC extension : statement expression
  *
@@ -388,11 +383,12 @@ bool AlsaLayer::alsa_set_params(snd_pcm_t *pcm_handle)
         ERROR("buffer to small, could not use");
         return false;
     }
+
 #undef HW
 
     DEBUG("%s using sampling rate %dHz",
-           (snd_pcm_stream(pcm_handle) == SND_PCM_STREAM_PLAYBACK) ? "playback" : "capture",
-           sampleRate_);
+          (snd_pcm_stream(pcm_handle) == SND_PCM_STREAM_PLAYBACK) ? "playback" : "capture",
+          sampleRate_);
 
     snd_pcm_sw_params_t *swparams = NULL;
     snd_pcm_sw_params_alloca(&swparams);
@@ -408,13 +404,14 @@ bool AlsaLayer::alsa_set_params(snd_pcm_t *pcm_handle)
 #undef TRY
 }
 
-//TODO first frame causes broken pipe (underrun) because not enough data are send --> make the handle wait to be ready
+// TODO first frame causes broken pipe (underrun) because not enough data is sent
+// we should wait until the handle is ready
 void
 AlsaLayer::write(void* buffer, int length, snd_pcm_t * handle)
 {
-    //Do not waste CPU cycle to handle void
+    // Skip empty buffers
     if (!length)
-       return;
+        return;
 
     snd_pcm_uframes_t frames = snd_pcm_bytes_to_frames(handle, length);
     watchdogTotalCount_++;
@@ -454,12 +451,14 @@ AlsaLayer::write(void* buffer, int length, snd_pcm_t * handle)
                     ERROR("Writing in state SND_PCM_STATE_SETUP, should be "
                           "SND_PCM_STATE_PREPARED or SND_PCM_STATE_RUNNING");
                     int error = snd_pcm_prepare(handle);
+
                     if (error < 0) {
                         ERROR("Failed to prepare handle: %s", snd_strerror(error));
                         stopPlaybackStream();
                     }
                 }
             }
+
             break;
         }
 
@@ -469,8 +468,9 @@ AlsaLayer::write(void* buffer, int length, snd_pcm_t * handle)
             break;
     }
 
-    //Detect when something is going wrong. This can be caused by alsa bugs or faulty encoder on the other side
-    //TODO do something useful instead of just warning and flushing buffers
+    // Detect when something is going wrong. This can be caused by alsa bugs or
+    // faulty encoder on the other side
+    // TODO do something useful instead of just warning and flushing buffers
     if (watchdogTotalErr_ > 0 && watchdogTotalCount_ / watchdogTotalErr_ >=4 && watchdogTotalCount_ > 50) {
         ERROR("Alsa: too many errors (%d error on %d frame)",watchdogTotalErr_,watchdogTotalCount_);
         flushUrgent();
@@ -539,13 +539,16 @@ namespace {
 bool safeUpdate(snd_pcm_t *handle, int &samples)
 {
     samples = snd_pcm_avail_update(handle);
+
     if (samples < 0) {
         samples = snd_pcm_recover(handle, samples, 0);
+
         if (samples < 0) {
             ERROR("Got unrecoverable error from snd_pcm_avail_update: %s", snd_strerror(samples));
             return false;
         }
     }
+
     return true;
 }
 
@@ -553,9 +556,10 @@ std::vector<std::string>
 getValues(const std::vector<HwIDPair> &deviceMap)
 {
     std::vector<std::string> audioDeviceList;
-    for (std::vector<HwIDPair>::const_iterator iter = deviceMap.begin();
-            iter != deviceMap.end(); ++iter)
-        audioDeviceList.push_back(iter->second);
+
+    for (const auto &dev : deviceMap)
+        audioDeviceList.push_back(dev.second);
+
     return audioDeviceList;
 }
 }
@@ -600,12 +604,11 @@ AlsaLayer::getAudioDeviceIndexMap(bool getCapture) const
 
                 if (snd_ctl_pcm_info(handle ,pcminfo) < 0) {
                     DEBUG(" Cannot get info");
-                }
-                else {
+                } else {
                     DEBUG("card %i : %s [%s]",
-                           numCard,
-                           snd_ctl_card_info_get_id(info),
-                           snd_ctl_card_info_get_name(info));
+                          numCard,
+                          snd_ctl_card_info_get_id(info),
+                          snd_ctl_card_info_get_name(info));
                     std::string description = snd_ctl_card_info_get_name(info);
                     description.append(" - ");
                     description.append(snd_pcm_info_get_name(pcminfo));
@@ -635,6 +638,7 @@ AlsaLayer::soundCardIndexExists(int card, PCMType stream)
     name.append(ss.str());
 
     snd_ctl_t* handle;
+
     if (snd_ctl_open(&handle, name.c_str(), 0) != 0)
         return false;
 
@@ -654,9 +658,9 @@ AlsaLayer::getAudioDeviceIndex(const std::string &description) const
     audioDeviceIndexMap.insert(audioDeviceIndexMap.end(), captureDevice.begin(), captureDevice.end());
     audioDeviceIndexMap.insert(audioDeviceIndexMap.end(), playbackDevice.begin(), playbackDevice.end());
 
-    for (std::vector<HwIDPair>::const_iterator iter = audioDeviceIndexMap.begin(); iter != audioDeviceIndexMap.end(); ++iter)
-        if (iter->second == description)
-            return iter->first;
+    for (const auto &dev : audioDeviceIndexMap)
+        if (dev.second == description)
+            return dev.first;
 
     // else return the default one
     return 0;
@@ -672,8 +676,10 @@ AlsaLayer::getAudioDeviceName(int index, PCMType type) const
         case SFL_PCM_PLAYBACK:
         case SFL_PCM_RINGTONE:
             return getPlaybackDeviceList().at(index);
+
         case SFL_PCM_CAPTURE:
             return getCaptureDeviceList().at(index);
+
         default:
             ERROR("Unexpected type %d", type);
             return "";
@@ -696,31 +702,28 @@ void AlsaLayer::capture()
     const int framesPerBufferAlsa = 2048;
     toGetSamples = std::min(framesPerBufferAlsa, toGetSamples);
 
-    std::vector<SFLDataFormat> in(toGetSamples);
-    SFLDataFormat * const in_ptr = &(*in.begin());
+    AudioBuffer in(toGetSamples, 1, sampleRate_);
+
+    // TODO: handle ALSA multichannel capture
+    const int toGetBytes = in.samples() * sizeof(SFLAudioSample);
+    SFLAudioSample * const in_ptr = in.getChannel(0)->data();
 
-    const int toGetBytes = in.size() * sizeof(in[0]);
     if (read(in_ptr, toGetBytes) != toGetBytes) {
         ERROR("ALSA MIC : Couldn't read!");
         return;
     }
 
-    AudioLayer::applyGain(in_ptr, toGetSamples, getCaptureGain());
+    in.applyGain(captureGain_);
 
     if (resample) {
         int outSamples = toGetSamples * (static_cast<double>(sampleRate_) / mainBufferSampleRate);
-        std::vector<SFLDataFormat> rsmpl_out(outSamples);
-        SFLDataFormat * const rsmpl_out_ptr = &(*rsmpl_out.begin());
-        converter_.resample(in_ptr, rsmpl_out_ptr,
-                rsmpl_out.size(), mainBufferSampleRate, sampleRate_,
-                toGetSamples);
-        dcblocker_.process(rsmpl_out_ptr, rsmpl_out_ptr, outSamples);
-        Manager::instance().getMainBuffer().putData(rsmpl_out_ptr,
-                rsmpl_out.size() * sizeof(rsmpl_out[0]), MainBuffer::DEFAULT_ID);
+        AudioBuffer rsmpl_out(outSamples, 1, mainBufferSampleRate);
+        converter_.resample(in, rsmpl_out);
+        dcblocker_.process(rsmpl_out);
+        Manager::instance().getMainBuffer().putData(rsmpl_out, MainBuffer::DEFAULT_ID);
     } else {
-        dcblocker_.process(in_ptr, in_ptr, toGetSamples);
-        Manager::instance().getMainBuffer().putData(in_ptr, toGetBytes,
-                                                     MainBuffer::DEFAULT_ID);
+        dcblocker_.process(in);
+        Manager::instance().getMainBuffer().putData(in, MainBuffer::DEFAULT_ID);
     }
 }
 
@@ -728,7 +731,8 @@ void AlsaLayer::playback(int maxSamples)
 {
     size_t bytesToGet = Manager::instance().getMainBuffer().availableForGet(MainBuffer::DEFAULT_ID);
 
-    const size_t bytesToPut = maxSamples * sizeof(SFLDataFormat);
+    const size_t bytesToPut = maxSamples * sizeof(SFLAudioSample);
+
     // no audio available, play tone or silence
     if (bytesToGet <= 0) {
         // FIXME: not thread safe! we only lock the mutex when we get the
@@ -736,14 +740,14 @@ void AlsaLayer::playback(int maxSamples)
         AudioLoop *tone = Manager::instance().getTelephoneTone();
         AudioLoop *file_tone = Manager::instance().getTelephoneFile();
 
-        std::vector<SFLDataFormat> out(maxSamples, 0);
-        SFLDataFormat * const out_ptr = &(*out.begin());
+        AudioBuffer out(maxSamples, 1, sampleRate_);
+
         if (tone)
-            tone->getNext(out_ptr, out.size(), getPlaybackGain());
+            tone->getNext(out, playbackGain_);
         else if (file_tone && !ringtoneHandle_)
-            file_tone->getNext(out_ptr, out.size(), getPlaybackGain());
+            file_tone->getNext(out, playbackGain_);
 
-        write(out_ptr, bytesToPut, playbackHandle_);
+        write(out.getChannel(0)->data(), bytesToPut, playbackHandle_);
     } else {
         // play the regular sound samples
 
@@ -752,6 +756,7 @@ void AlsaLayer::playback(int maxSamples)
 
         double resampleFactor = 1.0;
         size_t maxNbBytesToGet = bytesToPut;
+
         if (resample) {
             resampleFactor = static_cast<double>(sampleRate_) / mainBufferSampleRate;
             maxNbBytesToGet = bytesToGet / resampleFactor;
@@ -759,22 +764,21 @@ void AlsaLayer::playback(int maxSamples)
 
         bytesToGet = std::min(maxNbBytesToGet, bytesToGet);
 
-        const size_t samplesToGet = bytesToGet / sizeof(SFLDataFormat);
-        std::vector<SFLDataFormat> out(samplesToGet, 0);
-        SFLDataFormat * const out_ptr = &(*out.begin());
-        Manager::instance().getMainBuffer().getData(out_ptr, bytesToGet, MainBuffer::DEFAULT_ID);
-        AudioLayer::applyGain(out_ptr, samplesToGet, getPlaybackGain());
+        const size_t samplesToGet = bytesToGet / sizeof(SFLAudioSample);
+        //std::vector<SFLAudioSample> out(samplesToGet, 0);
+        AudioBuffer out(samplesToGet, 1, mainBufferSampleRate);
+
+        Manager::instance().getMainBuffer().getData(out, MainBuffer::DEFAULT_ID);
+        out.applyGain(playbackGain_);
 
         if (resample) {
             const size_t outSamples = samplesToGet * resampleFactor;
-            const size_t outBytes = outSamples * sizeof(SFLDataFormat);
-            std::vector<SFLDataFormat> rsmpl_out(outSamples);
-            SFLDataFormat * const rsmpl_out_ptr = &(*rsmpl_out.begin());
-            converter_.resample(out_ptr, rsmpl_out_ptr, rsmpl_out.size(),
-                    mainBufferSampleRate, sampleRate_, samplesToGet);
-            write(rsmpl_out_ptr, outBytes, playbackHandle_);
+            const size_t outBytes = outSamples * sizeof(SFLAudioSample);
+            AudioBuffer rsmpl_out(outSamples, 1, sampleRate_);
+            converter_.resample(out, rsmpl_out);
+            write(rsmpl_out.getChannel(0)->data(), outBytes, playbackHandle_);
         } else {
-            write(out_ptr, bytesToGet, playbackHandle_);
+            write(out.getChannel(0)->data(), bytesToGet, playbackHandle_);
         }
     }
 }
@@ -789,24 +793,22 @@ void AlsaLayer::audioCallback()
     snd_pcm_wait(playbackHandle_, 20);
 
     int playbackAvailSmpl = 0;
+
     if (not safeUpdate(playbackHandle_, playbackAvailSmpl))
         return;
-    const size_t playbackAvailBytes = playbackAvailSmpl * sizeof(SFLDataFormat);
 
-    size_t bytesToGet = urgentRingBuffer_.availableForGet(MainBuffer::DEFAULT_ID);
+    unsigned samplesToGet = urgentRingBuffer_.availableForGet(MainBuffer::DEFAULT_ID);
 
-    if (bytesToGet > 0) {
+    if (samplesToGet > 0) {
         // Urgent data (dtmf, incoming call signal) come first.
-        bytesToGet = std::min(bytesToGet, playbackAvailBytes);
-        const size_t samplesToGet = bytesToGet / sizeof(SFLDataFormat);
-        std::vector<SFLDataFormat> out(samplesToGet);
-        SFLDataFormat * const out_ptr = &(*out.begin());
-        urgentRingBuffer_.get(out_ptr, bytesToGet, MainBuffer::DEFAULT_ID);
-        AudioLayer::applyGain(out_ptr, samplesToGet, getPlaybackGain());
-
-        write(out_ptr, bytesToGet, playbackHandle_);
+        samplesToGet = std::min(samplesToGet, (unsigned)playbackAvailSmpl);
+        AudioBuffer out(samplesToGet);
+        urgentRingBuffer_.get(out, MainBuffer::DEFAULT_ID);
+        out.applyGain(playbackGain_);
+
+        write(out.getChannel(0)->data(), samplesToGet * sizeof(SFLAudioSample), playbackHandle_);
         // Consume the regular one as well (same amount of bytes)
-        Manager::instance().getMainBuffer().discard(bytesToGet, MainBuffer::DEFAULT_ID);
+        Manager::instance().getMainBuffer().discard(samplesToGet, MainBuffer::DEFAULT_ID);
     } else {
         // regular audio data
         playback(playbackAvailSmpl);
@@ -815,20 +817,19 @@ void AlsaLayer::audioCallback()
     if (ringtoneHandle_) {
         AudioLoop *file_tone = Manager::instance().getTelephoneFile();
         int ringtoneAvailSmpl = 0;
+
         if (not safeUpdate(ringtoneHandle_, ringtoneAvailSmpl))
             return;
-        int ringtoneAvailBytes = ringtoneAvailSmpl * sizeof(SFLDataFormat);
+        int ringtoneAvailBytes = ringtoneAvailSmpl * sizeof(SFLAudioSample);
 
-        std::vector<SFLDataFormat> out(ringtoneAvailSmpl, 0);
-        SFLDataFormat * const out_ptr = &(*out.begin());
+        AudioBuffer out(ringtoneAvailSmpl);
 
         if (file_tone) {
-            DEBUG("playback gain %d", getPlaybackGain());
-            file_tone->getNext(out_ptr, ringtoneAvailSmpl,
-                               getPlaybackGain());
+            DEBUG("playback gain %d", playbackGain_);
+            file_tone->getNext(out, playbackGain_);
         }
 
-        write(out_ptr, ringtoneAvailBytes, ringtoneHandle_);
+        write(out.getChannel(0)->data(), ringtoneAvailBytes, ringtoneHandle_);
     }
 
     // Additionally handle the mic's audio stream
@@ -842,12 +843,15 @@ void AlsaLayer::updatePreference(AudioPreference &preference, int index, PCMType
         case SFL_PCM_PLAYBACK:
             preference.setAlsaCardout(index);
             break;
+
         case AudioLayer::SFL_PCM_CAPTURE:
             preference.setAlsaCardin(index);
             break;
+
         case AudioLayer::SFL_PCM_RINGTONE:
             preference.setAlsaCardring(index);
             break;
+
         default:
             break;
     }
diff --git a/daemon/src/audio/audiobuffer.cpp b/daemon/src/audio/audiobuffer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1e19413aa97464e8c205c9b0070521279585798f
--- /dev/null
+++ b/daemon/src/audio/audiobuffer.cpp
@@ -0,0 +1,231 @@
+/*
+ *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
+ *  Author: Adrien Beraud <adrien.beraud@wisdomvibes.com>
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#include <iostream>
+#include "audiobuffer.h"
+
+AudioBuffer::AudioBuffer(size_t sample_num /* = 0 */, unsigned channel_num /* = 1 */, int sample_rate /* = 8000 */)
+    :  sampleRate_(sample_rate),
+       samples_(std::max(1U, channel_num),
+                std::vector<SFLAudioSample>(sample_num, 0))
+{
+}
+
+AudioBuffer::AudioBuffer(const SFLAudioSample* in, size_t sample_num, unsigned channel_num /* = 1 */, int sample_rate /* = 8000 */)
+    :  sampleRate_(sample_rate),
+       samples_((std::max(1U, channel_num)), std::vector<SFLAudioSample>(sample_num, 0))
+{
+    deinterleave(in, sample_num, channel_num);
+}
+
+AudioBuffer::AudioBuffer(const AudioBuffer& other, bool copy_content /* = false */)
+    :  sampleRate_(other.sampleRate_),
+       samples_(copy_content ? other.samples_ :
+                std::vector<std::vector<SFLAudioSample> >(other.samples_.size(), std::vector<SFLAudioSample>(other.samples_[0].size())))
+{}
+
+int AudioBuffer::getSampleRate() const
+{
+    return sampleRate_;
+}
+
+void AudioBuffer::setSampleRate(int sr)
+{
+    sampleRate_ = sr;
+}
+
+void AudioBuffer::setChannelNum(unsigned n, bool copy_content /* = false */)
+{
+    n = std::max(1U, n);
+
+    if (n == samples_.size())
+        return;
+
+    size_t start_size = 0;
+
+    if (not samples_.empty())
+        start_size = samples_[0].size();
+
+    if (copy_content and not samples_.empty())
+        samples_.resize(n, samples_[0]);
+    else
+        samples_.resize(n, std::vector<SFLAudioSample>(start_size, 0));
+}
+
+void AudioBuffer::resize(size_t sample_num)
+{
+    if (samples_[0].size() == sample_num)
+        return;
+
+    for (unsigned i = 0; i < samples_.size(); i++)
+        samples_[i].resize(sample_num);
+}
+
+void AudioBuffer::empty()
+{
+    for (unsigned i = 0; i < samples_.size(); i++)
+        samples_[i].clear();
+}
+
+std::vector<SFLAudioSample> * AudioBuffer::getChannel(unsigned chan /* = 0 */)
+{
+    if (chan < samples_.size())
+        return &samples_[chan];
+
+    return NULL;
+}
+
+void AudioBuffer::applyGain(unsigned int gain)
+{
+    if (gain != 100)
+        applyGain(gain * 0.01);
+}
+
+void AudioBuffer::applyGain(double gain)
+{
+    if (gain == 1.0) return;
+
+    for (unsigned i = 0; i < samples_.size(); i++)
+        for (unsigned j = 0; j < samples_[0].size(); j++)
+            samples_[i][j] *= gain;
+}
+
+size_t AudioBuffer::interleave(SFLAudioSample* out) const
+{
+    for (unsigned i = 0; i < samples_[0].size(); i++)
+        for (unsigned j = 0; j < samples_.size(); j++)
+            *out++ = samples_[j][i];
+
+    return samples_[0].size() * samples_.size();
+}
+
+size_t AudioBuffer::interleaveFloat(float* out) const
+{
+    for (unsigned i = 0; i < samples_[0].size(); i++)
+        for (unsigned j = 0; j < samples_.size(); j++)
+            *out++ = (float) samples_[j][i] * .000030517578125f;
+
+    return samples_[0].size() * samples_.size();
+}
+
+void AudioBuffer::deinterleave(const SFLAudioSample* in, size_t sample_num, unsigned channel_num)
+{
+    if (in == NULL)
+        return;
+
+    // Resize buffer
+    setChannelNum(channel_num);
+    resize(sample_num);
+
+    for (unsigned i = 0; i < samples_[0].size(); i++)
+        for (unsigned j = 0; j < samples_.size(); j++)
+            samples_[j][i] = *in++;
+}
+
+size_t AudioBuffer::mix(const AudioBuffer& other, bool up /* = true */)
+{
+    const bool upmix = up && (other.samples_.size() < samples_.size());
+    const size_t samp_num = std::min(samples_[0].size(), other.samples_[0].size());
+    const unsigned chan_num = upmix ? samples_.size() : std::min(samples_.size(), other.samples_.size());
+
+    for (unsigned i = 0; i < chan_num; i++) {
+        unsigned src_chan = upmix ? std::min<unsigned>(i, other.samples_.size() - 1) : i;
+
+        for (unsigned j = 0; j < samp_num; j++)
+            samples_[i][j] += other.samples_[src_chan][j];
+    }
+
+    return samp_num;
+}
+
+size_t AudioBuffer::copy(AudioBuffer& in, int sample_num /* = -1 */, size_t pos_in /* = 0 */, size_t pos_out /* = 0 */, bool up /* = true */)
+{
+    if (sample_num == -1)
+        sample_num = in.samples();
+
+    int to_copy = std::min((int)in.samples() - (int)pos_in, sample_num);
+
+    if (to_copy <= 0) return 0;
+
+    const bool upmix = up && (in.samples_.size() < samples_.size());
+    const size_t chan_num = upmix ? samples_.size() : std::min(in.samples_.size(), samples_.size());
+
+    if ((pos_out + to_copy) > samples_[0].size())
+        resize(pos_out + to_copy);
+
+    sampleRate_ = in.sampleRate_;
+    //setChannelNum(chan_num);
+
+    for (unsigned i = 0; i < chan_num; i++) {
+        size_t src_chan = upmix ? std::min<size_t>(i, in.samples_.size() - 1U) : i;
+        std::copy(in.samples_[src_chan].begin() + pos_in, in.samples_[src_chan].begin() + pos_in + to_copy, samples_[i].begin() + pos_out);
+    }
+
+    return to_copy;
+}
+
+size_t AudioBuffer::copy(SFLAudioSample* in, size_t sample_num, size_t pos_out /* = 0 */)
+{
+    if (in == NULL) return 0;
+
+    if ((pos_out + sample_num) > samples_[0].size())
+        resize(pos_out + sample_num);
+
+    const size_t chan_num = samples_.size();
+    unsigned i;
+
+    for (i = 0; i < chan_num; i++) {
+        std::copy(in, in + sample_num, samples_[i].begin() + pos_out);
+    }
+
+    return sample_num;
+}
+
+std::ostream& operator<<(std::ostream& os, const AudioBuffer& buf)
+{
+    for (unsigned i = 0; i < buf.samples_[0].size(); i++) {
+        for (unsigned j = 0; j < buf.samples_.size(); j++)
+            os << buf.samples_[j][i];
+    }
+
+    return os;
+}
+
+std::istream& operator>>(std::istream& is, AudioBuffer& buf)
+{
+    for (unsigned i = 0; ; i++) {
+        for (unsigned j = 0; j < buf.samples_.size(); j++) {
+            if (is && is.good())
+                is >> buf.samples_[j][i];
+            else
+                break;
+        }
+    }
+}
diff --git a/daemon/src/audio/audiobuffer.h b/daemon/src/audio/audiobuffer.h
new file mode 100644
index 0000000000000000000000000000000000000000..2128f86dd6c1836aa02d3e9fe878847d0cf4826d
--- /dev/null
+++ b/daemon/src/audio/audiobuffer.h
@@ -0,0 +1,212 @@
+/*
+ *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
+ *  Author: Adrien Beraud <adrien.beraud@wisdomvibes.com>
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#ifndef _AUDIO_BUFFER_H
+#define _AUDIO_BUFFER_H
+
+#include <iostream>
+#include <vector>
+#include <cstddef> // for size_t
+
+#include "sfl_types.h"
+
+class AudioBuffer {
+    public:
+        /**
+         * Default constructor.
+         */
+        AudioBuffer(size_t sample_num = 0, unsigned channel_num = 1, int sample_rate = 8000);
+
+        /**
+         * Construtor from existing interleaved data (copied into the buffer).
+         */
+        AudioBuffer(const SFLAudioSample* in, size_t sample_num, unsigned channel_num = 1, int sample_rate = 8000);
+
+        /**
+         * Copy constructor that by default only copies the buffer parameters (channel number, sample rate and buffer size).
+         * If copy_content is set to true, the other buffer content is also copied.
+         */
+        AudioBuffer(const AudioBuffer& other, bool copy_content = false);
+
+        void reset() {
+            for (std::vector<std::vector<SFLAudioSample> >::iterator i = samples_.begin(); i != samples_.end(); ++i)
+                std::fill(i->begin(), i->end(), 0);
+        }
+
+        /**
+         * Returns the sample rate (in samples/sec) associated to this buffer.
+         */
+        int getSampleRate() const;
+
+        /**
+         * Set the sample rate (in samples/sec) associated to this buffer.
+         */
+        void setSampleRate(int sr);
+
+        /**
+         * Returns the number of channels in this buffer.
+         */
+        inline unsigned channels() const {
+            return samples_.size();
+        }
+
+        /**
+         * Set the number of channels of this buffer.
+         *
+         * @param n: the new number of channels. If n < channels(), channels are removed from the buffer, otherwise the behavior depends on copy_first.
+         *
+         * @param copy_first: if set to true and n > channels(), new channels are initialised as a copy of the first channel (channel 0). If set to false, new channels are initialised to 0.
+         */
+        void setChannelNum(unsigned n, bool copy_first = false);
+
+        /**
+         * Returns the number of (multichannel) samples in this buffer.
+         */
+        inline size_t samples() const {
+            return samples_[0].size();
+        }
+
+        /**
+         * Return the total number of single samples in the buffer (same as samples()*channels()).
+         */
+        inline size_t capacity() const {
+            return samples() * channels();
+        }
+
+        /**
+         * Resize the buffer to make it able to hold sample_num multichannel samples.
+         */
+        void resize(size_t sample_num);
+
+        /**
+         * Set all samples in this buffer to 0. Buffer size is not changed.
+         */
+        void clear();
+
+        /**
+         * Resize the buffer to 0. All samples are lost but the number of channels and sample rate are kept.
+         */
+        void empty();
+
+        /**
+         * Return the data (audio samples) for a given channel number.
+         * Channel data can be modified but size of individual channel vectors should not be changed manually.
+         */
+        std::vector<SFLAudioSample> *getChannel(unsigned chan);
+
+        /**
+         * Return a pointer to the raw data in this buffer.
+         */
+        inline std::vector<std::vector<SFLAudioSample> > &getData() {
+            return samples_;
+        }
+
+        /**
+         * Write interleaved multichannel data to the out buffer (fixed-point 16-bits).
+         * The out buffer must be at least large by capacity()*sizeof(SFLAudioSample) bytes.
+         *
+         * @returns Number of samples writen.
+         */
+        size_t interleave(SFLAudioSample* out) const;
+
+        /**
+         * Write interleaved multichannel data to the out buffer, while samples are converted to float.
+         * The buffer must be at least of size getChannelNum()*samples()*sizeof(float).
+         *
+         * @returns Number of samples writen.
+         */
+        size_t interleaveFloat(float* out) const;
+
+        /**
+         * Import interleaved multichannel data. Internal buffer is resized as needed. Function will read sample_num*channel_num elements of the in buffer.
+         */
+        void deinterleave(const SFLAudioSample* in, size_t sample_num, unsigned channel_num = 1);
+
+        /**
+         * In-place gain transformation with integer parameter.
+         *
+         * @param gain: 0 -> 100 scale
+         */
+        void applyGain(unsigned int gain);
+
+        /**
+         * In-place gain transformation.
+         *
+         * @param gain: 0.0 -> 1.0 scale
+         */
+        void applyGain(double gain);
+
+        /**
+         * Mix elements of the other buffer within this buffer (in-place simple addition).
+         * If other.channels() is higher than this.channels(), only the first this.channels() channels are imported.
+         * If other.channels() is lower than this.channels(), behavior depends on upmix.
+         * Sample rate is not considered by this function.
+         *
+         * TODO: some kind of check for overflow/saturation.
+         *
+         * @param other: the other buffer to mix in this one.
+         * @param upmix: if true, upmixing occurs when other.channels() < this.channels().
+         *              If false, only the first other.channels() channels are edited in this buffer.
+         *
+         * @returns Number of samples modified.
+         */
+        size_t mix(const AudioBuffer& other, bool upmix = true);
+
+        /**
+         * Copy sample_num samples from in (from sample pos_in) to this buffer (at sample pos_out).
+         * If sample_num is -1 (the default), the entire in buffer is copied.
+         *
+         * The number of channels is changed to match the in channel number.
+         * Buffer sample number is also increased if required to hold the new requested samples.
+         */
+        size_t copy(AudioBuffer& in, int sample_num = -1, size_t pos_in = 0, size_t pos_out = 0, bool upmix = true);
+
+        /**
+         * Copy sample_num samples from in to this buffer (at sample pos_out).
+         * Input data is treated as mono and samples are duplicated in the case of a multichannel buffer.
+         *
+         * Buffer sample number is increased if required to hold the new requested samples.
+         */
+        size_t copy(SFLAudioSample* in, size_t sample_num, size_t pos_out = 0);
+
+        /**
+         * Overloading << and >> to easily import/export a multichannel stream
+         */
+        friend std::ostream& operator<<(std::ostream& os, const AudioBuffer& buf);
+        friend std::istream& operator>>(std::istream& is, AudioBuffer& buf);
+
+    private:
+        int sampleRate_;
+
+        // main buffers holding data for each channels
+        std::vector<std::vector<SFLAudioSample> > samples_;
+};
+
+#endif // _AUDIO_BUFFER_H
diff --git a/daemon/src/audio/audiolayer.cpp b/daemon/src/audio/audiolayer.cpp
index 33b7bbdcc4c93ca9e13f710b5552fec1e72efa2a..1b59a2b8778fbb15a39d332e3edb98b8fe37a4c5 100644
--- a/daemon/src/audio/audiolayer.cpp
+++ b/daemon/src/audio/audiolayer.cpp
@@ -35,11 +35,10 @@
 #include "manager.h"
 #include "scoped_lock.h"
 
-unsigned int AudioLayer::captureGain_ = 100;
-unsigned int AudioLayer::playbackGain_ = 100;
-
 AudioLayer::AudioLayer()
-    : isStarted_(false)
+    : captureGain_(100)
+    , playbackGain_(100)
+    , isStarted_(false)
     , playbackMode_(NONE)
     , urgentRingBuffer_(SIZEBUF, MainBuffer::DEFAULT_ID)
     , sampleRate_(Manager::instance().getMainBuffer().getInternalSamplingRate())
@@ -70,17 +69,10 @@ void AudioLayer::flushUrgent()
     urgentRingBuffer_.flushAll();
 }
 
-void AudioLayer::putUrgent(void* buffer, int toCopy)
+void AudioLayer::putUrgent(AudioBuffer& buffer)
 {
     sfl::ScopedLock guard(mutex_);
-    urgentRingBuffer_.put(buffer, toCopy);
-}
-
-void AudioLayer::applyGain(SFLDataFormat *src , int samples, int gain)
-{
-    if (gain != 100)
-        for (int i = 0 ; i < samples; i++)
-            src[i] = src[i] * gain* 0.01;
+    urgentRingBuffer_.put(buffer);
 }
 
 // Notify (with a beep) an incoming call when there is already a call in progress
@@ -103,11 +95,10 @@ void AudioLayer::notifyIncomingCall()
 
     Tone tone("440/160", getSampleRate());
     unsigned int nbSample = tone.getSize();
-    SFLDataFormat buf[nbSample];
-    tone.getNext(buf, nbSample);
+    AudioBuffer buf(nbSample);
+    tone.getNext(buf);
 
     /* Put the data in the urgent ring buffer */
     flushUrgent();
-    putUrgent(buf, sizeof buf);
+    putUrgent(buf);
 }
-
diff --git a/daemon/src/audio/audiolayer.h b/daemon/src/audio/audiolayer.h
index 8c9ba4640b8244051048109009cf739c0ff3703e..8ec0c67c9df965c404b81842614ddcfa6db025d2 100644
--- a/daemon/src/audio/audiolayer.h
+++ b/daemon/src/audio/audiolayer.h
@@ -50,6 +50,9 @@
 class MainBuffer;
 class AudioPreference;
 
+
+typedef std::vector<AudioBuffer> AudioBufferStack;
+
 namespace ost {
 class Time;
 }
@@ -121,9 +124,8 @@ class AudioLayer {
          * Send a chunk of data to the hardware buffer to start the playback
          * Copy data in the urgent buffer.
          * @param buffer The buffer containing the data to be played ( ringtones )
-         * @param toCopy The size of the buffer
          */
-        void putUrgent(void* buffer, int toCopy);
+        void putUrgent(AudioBuffer& buffer);
 
         /**
          * Flush main buffer
@@ -135,11 +137,6 @@ class AudioLayer {
          */
         void flushUrgent();
 
-        /**
-         * Apply gain to audio frame
-         */
-        static void applyGain(SFLDataFormat *src , int samples, int gain);
-
         /**
          * Convert audio amplitude value from linear value to dB
          */
@@ -164,7 +161,7 @@ class AudioLayer {
         /**
          * Set capture stream gain (microphone)
          */
-       unsigned int getCaptureGain(void) {
+        unsigned int getCaptureGain() const {
             return captureGain_;
         }
 
@@ -178,7 +175,7 @@ class AudioLayer {
         /**
          * Get playback stream gain (speaker)
          */
-        unsigned int getPlaybackGain(void) {
+        unsigned int getPlaybackGain() const {
             return playbackGain_;
         }
 
@@ -196,19 +193,20 @@ class AudioLayer {
          */
         void notifyIncomingCall();
 
+        virtual void updatePreference(AudioPreference &pref, int index, PCMType type) = 0;
+
+    protected:
+
         /**
          * Gain applied to mic signal
          */
-        static unsigned int captureGain_;
+        unsigned int captureGain_;
 
         /**
          * Gain applied to playback signal
          */
-        static unsigned int playbackGain_;
-
-        virtual void updatePreference(AudioPreference &pref, int index, PCMType type) = 0;
+        unsigned int playbackGain_;
 
-    protected:
         /**
          * Whether or not the audio layer stream is started
          */
@@ -243,6 +241,7 @@ class AudioLayer {
         SamplerateConverter converter_;
 
     private:
+
         /**
          * Time of the last incoming call notification
          */
diff --git a/daemon/src/audio/audioloop.cpp b/daemon/src/audio/audioloop.cpp
index dcd99204f66ebdc558a69b4bb93956688e927fa6..fad4d0d29f1f0bd5a26ea1f2f01488390e88d4b6 100644
--- a/daemon/src/audio/audioloop.cpp
+++ b/daemon/src/audio/audioloop.cpp
@@ -32,84 +32,72 @@
  *  as that of the covered work.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "audioloop.h"
-#include "manager.h"
-#include "dbus/callmanager.h"
+
 #include <cmath>
 #include <numeric>
 #include <cstring>
 #include <cassert>
 #include "logger.h"
 
-AudioLoop::AudioLoop(unsigned int sampleRate) : buffer_(0),  size_(0), pos_(0), sampleRate_(sampleRate), isRecording_(false)
-{}
+AudioLoop::AudioLoop(unsigned int sampleRate) : buffer_(0), pos_(0)
+{
+    buffer_ = new AudioBuffer;
+    buffer_->setSampleRate(sampleRate);
+}
 
 AudioLoop::~AudioLoop()
 {
-    delete [] buffer_;
+    delete buffer_;
 }
 
 void
 AudioLoop::seek(double relative_position)
 {
-    size_t new_pos = (size_t)((double)size_ * (relative_position * 0.01));
-
-    pos_ = new_pos;
+    pos_ = static_cast<double>(buffer_->samples() * relative_position * 0.01);
 }
 
-static unsigned int updatePlaybackScale = 0;
-
 void
-AudioLoop::getNext(SFLDataFormat* output, size_t total_samples, short volume)
+AudioLoop::getNext(AudioBuffer& output, unsigned int volume)
 {
+    if (!buffer_) {
+        ERROR("buffer is NULL");
+        return;
+    }
+
+    const size_t buf_samples = buffer_->samples();
     size_t pos = pos_;
+    size_t total_samples = output.samples();
+    size_t output_pos = 0;
 
-    if (size_ == 0) {
+    if (buf_samples == 0) {
         ERROR("Audio loop size is 0");
         return;
-    } else if (pos >= size_) {
+    } else if (pos >= buf_samples) {
         ERROR("Invalid loop position %d", pos);
         return;
     }
 
     while (total_samples > 0) {
-        size_t samples = total_samples;
+        size_t samples = std::min(total_samples, buf_samples - pos);
 
-        if (samples > (size_ - pos))
-            samples = size_ - pos;
+        output.copy(*buffer_, samples, pos, output_pos);
 
-        // short->char conversion
-        memcpy(output, buffer_ + pos, samples * sizeof(SFLDataFormat));
-
-        // Scaling needed
-        if (volume != 100) {
-            const double gain = volume * 0.01;
-
-            for (size_t i = 0; i < samples; ++i, ++output)
-                *output *= gain;
-        } else
-            output += samples; // this is the destination...
-
-        pos = (pos + samples) % size_;
+        output_pos += samples;
+        pos = (pos + samples) % buf_samples;
 
         total_samples -= samples;
     }
 
-    pos_ = pos;
+    output.applyGain(volume); // apply volume
 
-    // We want to send values in milisecond
-    int divisor = sampleRate_ / 1000;
-    if(divisor == 0) {
-        ERROR("Error cannot update playback slider, sampling rate is 0");
-        return;
-    }
+    pos_ = pos;
 
-    if(isRecording_) {
-        if((updatePlaybackScale % 5) == 0) {
-            CallManager *cm = Manager::instance().getDbusManager()->getCallManager();
-            cm->updatePlaybackScale(pos_ / divisor, size_ / divisor);
-        }
-        updatePlaybackScale++;
-    }
+    onBufferFinish();
 }
 
+void AudioLoop::onBufferFinish() {}
diff --git a/daemon/src/audio/audioloop.h b/daemon/src/audio/audioloop.h
index c8bc3372c8da20b99387a11af712467911de59e5..b401fde7a38a3e12b3a39d45cb779f8b9b884ce2 100644
--- a/daemon/src/audio/audioloop.h
+++ b/daemon/src/audio/audioloop.h
@@ -36,6 +36,7 @@
 #include "sfl_types.h"
 #include <cstring>
 #include "noncopyable.h"
+#include "audiobuffer.h"
 
 /**
  * @file audioloop.h
@@ -55,7 +56,7 @@ class AudioLoop {
          * @param nb of int16 to send
          * @param volume  The volume
          */
-        void getNext(SFLDataFormat* output, size_t samples, short volume=100);
+        void getNext(AudioBuffer& output, unsigned int volume=100);
 
         void seek(double relative_position);
 
@@ -70,36 +71,20 @@ class AudioLoop {
          * Accessor to the size of the buffer
          * @return unsigned int The size
          */
-        size_t getSize() const {
-            return size_;
+        size_t getSize() {
+            return buffer_->samples();
         }
 
-        /**
-         * This should be set to true for recording playback
-         */
-        void setIsRecording(bool isRec) {
-           isRecording_ = isRec;
-        }
-
-
     protected:
         /** The data buffer */
-        SFLDataFormat* buffer_;
-
-        /** Number of samples inside the buffer */
-        size_t size_;
+        AudioBuffer * buffer_;
 
         /** current position, set to 0, when initialize */
         size_t pos_;
 
-        /** Sample rate */
-        unsigned int sampleRate_;
-
-        /** Is a playback recording */
-        bool isRecording_;
-
     private:
         NON_COPYABLE(AudioLoop);
+        virtual void onBufferFinish();
 };
 
 #endif // __AUDIOLOOP_H__
diff --git a/daemon/src/audio/audiorecord.cpp b/daemon/src/audio/audiorecord.cpp
index 14b30ddf1afe857b72eb48b66e5da23d448781d9..7d0da92c140816c000306f2df1abafd93fb97e05 100644
--- a/daemon/src/audio/audiorecord.cpp
+++ b/daemon/src/audio/audiorecord.cpp
@@ -33,6 +33,7 @@
 #endif
 
 #include "audiorecord.h"
+#include <sndfile.hh>
 #include <unistd.h>
 #include <sstream> // for stringstream
 #include <algorithm>
@@ -40,24 +41,6 @@
 #include "logger.h"
 #include "fileutils.h"
 
-// structure for the wave header
-
-struct wavhdr {
-    char riff[4];           // "RIFF"
-    SINT32 file_size;       // in bytes
-    char wave[4];           // "WAVE"
-    char fmt[4];            // "fmt "
-    SINT32 chunk_size;      // in bytes (16 for PCM)
-    SINT16 format_tag;      // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law
-    SINT16 num_chans;       // 1=mono, 2=stereo
-    SINT32 sample_rate;
-    SINT32 bytes_per_sec;
-    SINT16 bytes_per_samp;  // 2=16-bit mono, 4=16-bit stereo
-    SINT16 bits_per_samp;
-    char data[4];           // "data"
-    SINT32 data_length;     // in bytes
-};
-
 namespace {
 std::string
 createFilename()
@@ -106,29 +89,27 @@ createFilename()
 }
 
 
-AudioRecord::AudioRecord() : fileHandle_(NULL)
-    , fileType_(FILE_INVALID)
+AudioRecord::AudioRecord() : fileHandle_(0)
     , channels_(1)
-    , byteCounter_(0)
     , sndSmplRate_(8000)
-    , nbSamplesMic_(0)
-    , nbSamplesSpk_(0)
     , recordingEnabled_(false)
-    , mixBuffer_()
-    , micBuffer_()
-    , spkBuffer_()
     , filename_(createFilename())
     , savePath_()
 {
     WARN("Generate filename for this call %s ", filename_.c_str());
 }
 
+AudioRecord::~AudioRecord()
+{
+    delete fileHandle_;
+}
+
 void AudioRecord::setSndSamplingRate(int smplRate)
 {
     sndSmplRate_ = smplRate;
 }
 
-void AudioRecord::setRecordingOption(FILE_TYPE type, int sndSmplRate, const std::string &path)
+void AudioRecord::setRecordingOptions(int sndSmplRate, const std::string &path)
 {
     std::string filePath;
 
@@ -139,7 +120,6 @@ void AudioRecord::setRecordingOption(FILE_TYPE type, int sndSmplRate, const std:
         filePath = path;
     }
 
-    fileType_ = type;
     channels_ = 1;
     sndSmplRate_ = sndSmplRate;
     savePath_ = (*filePath.rbegin() == DIR_SEPARATOR_CH) ? filePath : filePath + DIR_SEPARATOR_STR;
@@ -149,7 +129,7 @@ namespace {
 bool
 nonFilenameCharacter(char c)
 {
-    return not (std::isalnum(c) or c == '_' or c == '.');
+    return not(std::isalnum(c) or c == '_' or c == '.');
 }
 
 // Replace any character that is inappropriate for a filename with '_'
@@ -166,16 +146,9 @@ void AudioRecord::initFilename(const std::string &peerNumber)
     std::string fName(filename_);
     fName.append("-" + sanitize(peerNumber) + "-" PACKAGE);
 
-    if (fileType_ == FILE_RAW) {
-        if (filename_.find(".raw") == std::string::npos) {
-            DEBUG("Concatenate .raw file extension: name : %s", filename_.c_str());
-            fName.append(".raw");
-        }
-    } else if (fileType_ == FILE_WAV) {
-        if (filename_.find(".wav") == std::string::npos) {
-            DEBUG("Concatenate .wav file extension: name : %s", filename_.c_str());
-            fName.append(".wav");
-        }
+    if (filename_.find(".wav") == std::string::npos) {
+        DEBUG("Concatenate .wav file extension: name : %s", filename_.c_str());
+        fName.append(".wav");
     }
 
     savePath_.append(fName);
@@ -189,34 +162,30 @@ std::string AudioRecord::getFilename() const
 bool AudioRecord::openFile()
 {
     bool result = false;
+    delete fileHandle_;
+    const bool doAppend = fileExists();
+    const int access = doAppend ? SFM_RDWR : SFM_WRITE;
 
-    if (not fileExists()) {
-        DEBUG("Filename does not exist, creating one");
-        byteCounter_ = 0;
+    fileHandle_ = new SndfileHandle(savePath_.c_str(), access, SF_FORMAT_WAV | SF_FORMAT_PCM_16, channels_, sndSmplRate_);
 
-        if (fileType_ == FILE_RAW)
-            result = setRawFile();
-        else if (fileType_ == FILE_WAV)
-            result = setWavFile();
-    } else {
-        DEBUG("Filename already exists, opening it");
-        if (fileType_ == FILE_RAW)
-            result = openExistingRawFile();
-        else if (fileType_ == FILE_WAV)
-            result = openExistingWavFile();
+    // check overloaded boolean operator
+    if (!*fileHandle_) {
+        WARN("Could not open WAV file!");
+        delete fileHandle_;
+        fileHandle_ = 0;
+        return false;
     }
 
+    if (doAppend and fileHandle_->seek(0, SEEK_END) < 0)
+        WARN("Couldn't seek to the end of the file ");
+
     return result;
 }
 
 void AudioRecord::closeFile()
 {
-    if (fileHandle_ == 0) return;
-
-    if (fileType_ == FILE_RAW)
-        fclose(fileHandle_);
-    else if (fileType_ == FILE_WAV)
-        closeWavFile();
+    delete fileHandle_;
+    fileHandle_ = 0;
 }
 
 bool AudioRecord::isOpenFile() const
@@ -242,6 +211,7 @@ bool AudioRecord::toggleRecording()
         openFile();
         recordingEnabled_ = true;
     }
+
     return recordingEnabled_;
 }
 
@@ -251,185 +221,22 @@ void AudioRecord::stopRecording()
     recordingEnabled_ = false;
 }
 
-bool AudioRecord::setRawFile()
-{
-    fileHandle_ = fopen(savePath_.c_str(), "wb");
-
-    if (!fileHandle_) {
-        WARN("Could not create RAW file!");
-        return false;
-    }
-
-    DEBUG("created RAW file.");
-
-    return true;
-}
-
-namespace {
-    std::string header_to_string(const wavhdr &hdr)
-    {
-        std::stringstream ss;
-        ss << hdr.riff << "\0 "
-           << hdr.file_size << " "
-           << hdr.wave << "\0 "
-           << hdr.fmt << "\0 "
-           << hdr.chunk_size << " "
-           << hdr.format_tag << " "
-           << hdr.num_chans << " "
-           << hdr.sample_rate << " "
-           << hdr.bytes_per_sec << " "
-           << hdr.bytes_per_samp << " "
-           << hdr.bits_per_samp << " "
-           << hdr.data << "\0 "
-           << hdr.data_length;
-        return ss.str();
-    }
-}
-
-bool AudioRecord::setWavFile()
-{
-    DEBUG("Create new wave file %s, sampling rate: %d", savePath_.c_str(), sndSmplRate_);
-
-    fileHandle_ = fopen(savePath_.c_str(), "wb");
-
-    if (!fileHandle_) {
-        WARN("Could not create WAV file.");
-        return false;
-    }
-
-    /* The text fields are NOT supposed to be null terminated, so we have to
-     * write them as arrays since strings enclosed in quotes include a
-     * null character */
-    wavhdr hdr = {{'R', 'I', 'F', 'F'},
-                  44,
-                  {'W', 'A', 'V', 'E'},
-                  {'f','m', 't', ' '},
-                  16,
-                  1,
-                  channels_,
-                  sndSmplRate_,
-                  -1, /* initialized below */
-                  -1, /* initialized below */
-                  16,
-                  {'d', 'a', 't', 'a'},
-                  0};
-
-    hdr.bytes_per_samp = channels_ * hdr.bits_per_samp / 8;
-    hdr.bytes_per_sec = hdr.sample_rate * hdr.bytes_per_samp;
-
-    if (fwrite(&hdr, 4, 11, fileHandle_) != 11) {
-        WARN("Could not write WAV header for file. ");
-        return false;
-    }
-
-    DEBUG("Wrote wave header \"%s\"", header_to_string(hdr).c_str());
-    return true;
-}
-
-bool AudioRecord::openExistingRawFile()
-{
-    fileHandle_ = fopen(filename_.c_str(), "ab+");
-
-    if (!fileHandle_) {
-        WARN("could not create RAW file!");
-        return false;
-    }
-
-    return true;
-}
-
-bool AudioRecord::openExistingWavFile()
+void AudioRecord::recData(AudioBuffer& buffer)
 {
-    DEBUG("Opening %s", filename_.c_str());
-
-    fileHandle_ = fopen(filename_.c_str(), "rb+");
-
-    if (!fileHandle_) {
-        WARN("Could not open WAV file!");
-        return false;
-    }
-
-    if (fseek(fileHandle_, 40, SEEK_SET) != 0)  // jump to data length
-        WARN("Couldn't seek offset 40 in the file ");
-
-    if (fread(&byteCounter_, 4, 1, fileHandle_))
-        WARN("bytecounter Read successfully ");
-
-    if (fseek(fileHandle_, 0 , SEEK_END) != 0)
-        WARN("Couldn't seek at the en of the file ");
-
-
-    if (fclose(fileHandle_) != 0)
-        WARN("Can't close file r+ ");
-
-    fileHandle_ = fopen(filename_.c_str(), "ab+");
-
-    if (!fileHandle_) {
-        WARN("Could not createopen WAV file ab+!");
-        return false;
-    }
-
-    if (fseek(fileHandle_, 4 , SEEK_END) != 0)
-        WARN("Couldn't seek at the en of the file ");
-
-    return true;
-
-}
+    if (not recordingEnabled_)
+        return;
 
-void AudioRecord::closeWavFile()
-{
     if (fileHandle_ == 0) {
-        DEBUG("Can't closeWavFile, a file has not yet been opened!");
+        DEBUG("Can't record data, a file has not yet been opened!");
         return;
     }
 
-    DEBUG("Close wave file");
-
-    SINT32 bytes = byteCounter_ * channels_;
-
-    // jump to data length
-    if (fseek(fileHandle_, 40, SEEK_SET) != 0)
-        WARN("Could not seek in file");
-
-    if (ferror(fileHandle_))
-        WARN("Can't reach offset 40 while closing");
-
-    fwrite(&bytes, sizeof(SINT32), 1, fileHandle_);
-
-    if (ferror(fileHandle_))
-        WARN("Can't write bytes for data length ");
+    const int nSamples = buffer.samples();
 
-    bytes = byteCounter_ * channels_ + 44; // + 44 for the wave header
-
-    // jump to file size
-    if (fseek(fileHandle_, 4, SEEK_SET) != 0)
-        WARN("Could not seek in file");
-
-    if (ferror(fileHandle_))
-        WARN("Can't reach offset 4");
-
-    fwrite(&bytes, 4, 1, fileHandle_);
-
-    if (ferror(fileHandle_))
-        WARN("Can't reach offset 4");
-
-    if (fclose(fileHandle_) != 0)
-        WARN("Can't close file");
-}
-
-void AudioRecord::recData(SFLDataFormat* buffer, size_t nSamples)
-{
-    if (recordingEnabled_) {
-        if (fileHandle_ == 0) {
-            DEBUG("Can't record data, a file has not yet been opened!");
-            return;
-        }
-
-        if (fwrite(buffer, sizeof(SFLDataFormat), nSamples, fileHandle_) != nSamples)
-            WARN("Could not record data! ");
-        else {
-            fflush(fileHandle_);
-            byteCounter_ += nSamples * sizeof(SFLDataFormat);
-        }
+    // FIXME: mono only
+    if (fileHandle_->write(buffer.getChannel(0)->data(), nSamples) != nSamples) {
+        WARN("Could not record data!");
+    } else {
+        fileHandle_->writeSync();
     }
 }
diff --git a/daemon/src/audio/audiorecord.h b/daemon/src/audio/audiorecord.h
index 3fb91948e8c98edb1c13ac6b817b6203448f3481..6ebd35369afd7eca8e6148e1bf11c091bb6338e3 100644
--- a/daemon/src/audio/audiorecord.h
+++ b/daemon/src/audio/audiorecord.h
@@ -37,16 +37,18 @@
 
 #include "sfl_types.h"
 #include "noncopyable.h"
+#include "audiobuffer.h"
+
+class SndfileHandle;
 
 class AudioRecord {
 
     public:
-        enum FILE_TYPE { FILE_RAW, FILE_WAV, FILE_INVALID };
-
         AudioRecord();
+        ~AudioRecord();
 
         void setSndSamplingRate(int smplRate);
-        void setRecordingOption(FILE_TYPE type, int sndSmplRate, const std::string &path);
+        void setRecordingOptions(int sndSmplRate, const std::string &path);
 
         /**
          * Init recording file path
@@ -102,20 +104,11 @@ class AudioRecord {
          * @param buffer  The data chunk to be recorded
          * @param nSamples Number of samples (number of bytes) to be recorded
          */
-        void recData(SFLDataFormat* buffer, size_t nSamples);
+        //void recData(SFLDataFormat* buffer, size_t nSamples);
+        void recData(AudioBuffer& buffer);
 
     protected:
 
-        /**
-         * Set the header for raw files
-         */
-        bool setRawFile();
-
-        /**
-         * Set the header for wave files
-         */
-        bool setWavFile();
-
         /**
          * Open an existing raw file, used when the call is set on hold
          */
@@ -135,38 +128,18 @@ class AudioRecord {
         /**
          * Pointer to the recorded file
          */
-        FILE *fileHandle_;
-
-        /**
-         * File format (RAW / WAVE)
-         */
-        FILE_TYPE fileType_;
+        SndfileHandle *fileHandle_;
 
         /**
          * Number of channels
          */
-        SINT16 channels_;
-
-        /**
-         * Number of byte recorded
-         */
-        unsigned long byteCounter_;
+        int16_t channels_;
 
         /**
          * Sampling rate
          */
         int sndSmplRate_;
 
-        /**
-         * number of samples recorded for mic buffer
-         */
-        int nbSamplesMic_;
-
-        /**
-         * number of samples recorded for speaker buffer
-         */
-        int nbSamplesSpk_;
-
         /**
          * Maximum number of samples
          */
@@ -177,21 +150,6 @@ class AudioRecord {
          */
         bool recordingEnabled_;
 
-        /**
-         * Buffer used for mixing two channels
-         */
-        SFLDataFormat mixBuffer_[NB_SAMPLES_MAX];
-
-        /**
-         * Buffer used to copy mic info
-         */
-        SFLDataFormat micBuffer_[NB_SAMPLES_MAX];
-
-        /**
-         * Buffer used to copy spkr info
-         */
-        SFLDataFormat spkBuffer_[NB_SAMPLES_MAX];
-
         /**
          * Filename for this recording
          */
diff --git a/daemon/src/audio/audiorecorder.cpp b/daemon/src/audio/audiorecorder.cpp
index 6b7fc65ff9d22d4e1464e243549290db853ae475..e1950226ad6b12adc12eb7057d23e30fe7eb691d 100644
--- a/daemon/src/audio/audiorecorder.cpp
+++ b/daemon/src/audio/audiorecorder.cpp
@@ -38,11 +38,9 @@
 
 int AudioRecorder::count_ = 0;
 
-AudioRecorder::AudioRecorder(AudioRecord  *arec, MainBuffer *mb) :
+AudioRecorder::AudioRecorder(AudioRecord  *arec, MainBuffer &mb) :
     recorderId_(), mbuffer_(mb), arecord_(arec), running_(false), thread_(0)
 {
-    assert(mb);
-
     ++count_;
 
     std::string id("processid_");
@@ -56,8 +54,10 @@ AudioRecorder::AudioRecorder(AudioRecord  *arec, MainBuffer *mb) :
     recorderId_ = id.append(s);
 }
 
-AudioRecorder::~AudioRecorder() {
+AudioRecorder::~AudioRecorder()
+{
     running_ = false;
+
     if (thread_)
         pthread_join(thread_, NULL);
 }
@@ -81,16 +81,16 @@ AudioRecorder::runCallback(void *data)
  */
 void AudioRecorder::run()
 {
-    const size_t BUFFER_LENGTH = 10000;
-    std::tr1::array<SFLDataFormat, BUFFER_LENGTH> buffer;
-    buffer.assign(0);
+    static const size_t BUFFER_LENGTH = 10000;
+    AudioBuffer buffer(BUFFER_LENGTH);
 
     while (running_) {
-        const size_t availableBytes = mbuffer_->availableForGet(recorderId_);
-        mbuffer_->getData(buffer.data(), std::min(availableBytes, buffer.size()), recorderId_);
+        const size_t availableSamples = mbuffer_.availableForGet(recorderId_);
+        buffer.resize(std::min(availableSamples, BUFFER_LENGTH));
+        mbuffer_.getData(buffer, recorderId_);
 
-        if (availableBytes > 0)
-            arecord_->recData(buffer.data(), availableBytes / sizeof(SFLDataFormat));
+        if (availableSamples > 0)
+            arecord_->recData(buffer);
 
         usleep(20000); // 20 ms
     }
diff --git a/daemon/src/audio/audiorecorder.h b/daemon/src/audio/audiorecorder.h
index 0a471e37f9b0144b2b91f2ce210f1cf6f4878609..00bff8679dfb010ca25c5968a1edd497e61ea6f5 100644
--- a/daemon/src/audio/audiorecorder.h
+++ b/daemon/src/audio/audiorecorder.h
@@ -41,7 +41,7 @@ class MainBuffer;
 class AudioRecorder {
 
     public:
-        AudioRecorder(AudioRecord  *arec, MainBuffer *mb);
+        AudioRecorder(AudioRecord  *arec, MainBuffer &mb);
         ~AudioRecorder();
         std::string getRecorderID() const {
             return recorderId_;
@@ -56,7 +56,7 @@ class AudioRecorder {
 
         static int count_;
         std::string recorderId_;
-        MainBuffer *mbuffer_;
+        MainBuffer &mbuffer_;
         AudioRecord *arecord_;
         bool running_;
         pthread_t thread_;
diff --git a/daemon/src/audio/audiortp/audio_rtp_factory.cpp b/daemon/src/audio/audiortp/audio_rtp_factory.cpp
index 07483788087a9f668b930ea0473d6164563212c6..a97c2d3ea689d62b20e647e20539b0ce08c8cd69 100644
--- a/daemon/src/audio/audiortp/audio_rtp_factory.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_factory.cpp
@@ -68,6 +68,7 @@ AudioRtpFactory::~AudioRtpFactory()
 void AudioRtpFactory::initConfig()
 {
     DEBUG("AudioRtpFactory: init config");
+
     if (rtpSession_ != NULL)
         stop();
 
@@ -78,18 +79,22 @@ void AudioRtpFactory::initConfig()
     if (account) {
         srtpEnabled_ = account->getSrtpEnabled();
         std::string key(account->getSrtpKeyExchange());
+
         if (srtpEnabled_) {
 #if HAVE_ZRTP
+
             if (key == "sdes")
                 keyExchangeProtocol_ = SDES;
             else if (key == "zrtp")
                 keyExchangeProtocol_ = ZRTP;
+
 #else
-                keyExchangeProtocol_ = SDES;
+            keyExchangeProtocol_ = SDES;
 #endif
         } else {
             keyExchangeProtocol_ = NONE;
         }
+
         helloHashEnabled_ = account->getZrtpHelloHash();
     } else {
         srtpEnabled_ = false;
@@ -107,14 +112,18 @@ void AudioRtpFactory::initSession()
 
         switch (keyExchangeProtocol_) {
 #if HAVE_ZRTP
+
             case ZRTP:
                 rtpSession_ = new AudioZrtpSession(*ca_, zidFilename);
+
                 // TODO: be careful with that. The hello hash is computed asynchronously. Maybe it's
                 // not even available at that point.
                 if (helloHashEnabled_)
                     ca_->getLocalSDP()->setZrtpHash(static_cast<AudioZrtpSession *>(rtpSession_)->getHelloHash());
+
                 break;
 #endif
+
             case SDES:
                 rtpSession_ = new AudioSrtpSession(*ca_);
                 break;
@@ -175,8 +184,10 @@ void AudioRtpFactory::updateSessionMedia(const std::vector<AudioCodec*> &audioCo
 
 void AudioRtpFactory::updateDestinationIpAddress()
 {
-    if (rtpSession_)
-        rtpSession_->updateDestinationIpAddress();
+    if (rtpSession_ == NULL)
+        throw AudioRtpFactoryException("RTP session was null when trying to update IP address");
+
+    rtpSession_->updateDestinationIpAddress();
 }
 
 #if HAVE_ZRTP
@@ -192,6 +203,7 @@ AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession()
 void AudioRtpFactory::initLocalCryptoInfo()
 {
     DEBUG("AudioRtpFactory: Init local crypto info");
+
     if (rtpSession_ && keyExchangeProtocol_ == SDES) {
         AudioSrtpSession *srtp = static_cast<AudioSrtpSession*>(rtpSession_);
         // the context is invalidated and deleted by the call to initLocalCryptoInfo
@@ -203,6 +215,7 @@ void AudioRtpFactory::initLocalCryptoInfo()
 void AudioRtpFactory::initLocalCryptoInfoOnOffHold()
 {
     DEBUG("AudioRtpFactory: Init local crypto info");
+
     if (rtpSession_ && keyExchangeProtocol_ == SDES) {
         AudioSrtpSession *srtp = static_cast<AudioSrtpSession*>(rtpSession_);
         // the context is invalidated and deleted by the call to initLocalCryptoInfo
@@ -214,7 +227,7 @@ void AudioRtpFactory::initLocalCryptoInfoOnOffHold()
 
 void AudioRtpFactory::setRemoteCryptoInfo(SdesNegotiator& nego)
 {
-    if (rtpSession_ ) {
+    if (rtpSession_) {
         if (keyExchangeProtocol_ == SDES) {
             AudioSrtpSession *srtp = static_cast<AudioSrtpSession *>(rtpSession_);
             srtp->setRemoteCryptoInfo(nego);
diff --git a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
index 38949b5422273a62e88d48b7c1e9ce585dcc7856..f51a08d610f683cc23db5602c098095f44a2e14c 100644
--- a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
  *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *  Author: Adrien Beraud <adrien.beraud@wisdomvibes.com>
  *
  *  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
@@ -43,37 +44,41 @@
 namespace sfl {
 
 #ifdef RECTODISK
-std::ofstream rtpResampled ("testRtpOutputResampled.raw", std::ifstream::binary);
+std::ofstream rtpResampled("testRtpOutputResampled.raw", std::ifstream::binary);
 std::ofstream rtpNotResampled("testRtpOutput.raw", std::ifstream::binary);
 #endif
 
 DTMFEvent::DTMFEvent(char digit) : payload(), newevent(true), length(1000)
 {
-/*
-   From RFC2833:
-
-   Event  encoding (decimal)
-   _________________________
-   0--9                0--9
-   *                     10
-   #                     11
-   A--D              12--15
-   Flash                 16
-*/
+    /*
+       From RFC2833:
+
+       Event  encoding (decimal)
+       _________________________
+       0--9                0--9
+       *                     10
+       #                     11
+       A--D              12--15
+       Flash                 16
+    */
 
     switch (digit) {
         case '*':
             digit = 10;
             break;
+
         case '#':
             digit = 11;
             break;
+
         case 'A' ... 'D':
             digit = digit - 'A' + 12;
             break;
+
         case '0' ... '9':
             digit = digit - '0';
             break;
+
         default:
             ERROR("Unexpected DTMF %c", digit);
     }
@@ -85,7 +90,7 @@ DTMFEvent::DTMFEvent(char digit) : payload(), newevent(true), length(1000)
 }
 
 AudioRtpRecord::AudioRtpRecord() :
-      callId_("")
+    callId_("")
     , codecSampleRate_(0)
     , dtmfQueue_()
     , audioCodecs_()
@@ -93,7 +98,7 @@ AudioRtpRecord::AudioRtpRecord() :
     , encoderPayloadType_(0)
     , decoderPayloadType_(0)
     , hasDynamicPayloadType_(false)
-    , decData_()     // std::tr1::arrays will be 0-initialized
+    , decData_(DEC_BUFFER_SIZE)     // std::tr1::arrays will be 0-initialized
     , resampledData_()
     , encodedData_()
     , converterEncode_(0)
@@ -133,14 +138,16 @@ AudioRtpRecord::getCurrentCodec() const
         ERROR("No codec found");
         return 0;
     }
+
     return audioCodecs_[currentCodecIndex_];
 }
 
 void
 AudioRtpRecord::deleteCodecs()
 {
-    for (std::vector<AudioCodec *>::iterator i = audioCodecs_.begin(); i != audioCodecs_.end(); ++i)
-        delete *i;
+    for (auto &i : audioCodecs_)
+        delete i;
+
     audioCodecs_.clear();
 }
 
@@ -164,9 +171,9 @@ bool AudioRtpRecord::tryToSwitchPayloadTypes(int newPt)
 AudioRtpRecord::~AudioRtpRecord()
 {
     dead_ = true;
-#ifdef RECTODISK
-    rtpResampled.close();
-    rtpNotResampled.close();
+#ifdef RTP_DECODE_RECTODISK
+    beforedecode.close();
+    afterdecode.close();
 #endif
 
     delete converterEncode_;
@@ -193,7 +200,6 @@ AudioRtpRecord::~AudioRtpRecord()
 #endif
 }
 
-
 AudioRtpRecordHandler::AudioRtpRecordHandler(SIPCall &call) :
     audioRtpRecord_(),
     id_(call.getCallId()),
@@ -202,7 +208,9 @@ AudioRtpRecordHandler::AudioRtpRecordHandler(SIPCall &call) :
 {}
 
 
-AudioRtpRecordHandler::~AudioRtpRecordHandler() {}
+AudioRtpRecordHandler::~AudioRtpRecordHandler()
+{
+}
 
 std::string
 AudioRtpRecordHandler::getCurrentAudioCodecNames()
@@ -211,10 +219,11 @@ AudioRtpRecordHandler::getCurrentAudioCodecNames()
     ScopedLock lock(audioRtpRecord_.audioCodecMutex_);
     {
         std::string sep = "";
-        for (std::vector<AudioCodec*>::const_iterator i = audioRtpRecord_.audioCodecs_.begin();
-                i != audioRtpRecord_.audioCodecs_.end(); ++i) {
-            if (*i)
-                result += sep + (*i)->getMimeSubtype();
+
+        for (auto &i : audioRtpRecord_.audioCodecs_) {
+            if (i)
+                result += sep + i->getMimeSubtype();
+
             sep = " ";
         }
     }
@@ -229,6 +238,7 @@ void AudioRtpRecordHandler::setRtpMedia(const std::vector<AudioCodec*> &audioCod
     audioRtpRecord_.deleteCodecs();
     // Set various codec info to reduce indirection
     audioRtpRecord_.audioCodecs_ = audioCodecs;
+
     if (audioCodecs.empty()) {
         ERROR("Audio codecs empty");
         return;
@@ -283,60 +293,62 @@ int AudioRtpRecordHandler::processDataEncode()
 
     double resampleFactor = (double) mainBufferSampleRate / codecSampleRate;
 
-    // compute nb of byte to get coresponding to 1 audio frame
-    int samplesToGet = resampleFactor * getCodecFrameSize();
-    const size_t bytesToGet = samplesToGet * sizeof(SFLDataFormat);
+    // compute nb of byte to get corresponding to 1 audio frame
+    const size_t samplesToGet = resampleFactor * getCodecFrameSize();
 
-    if (Manager::instance().getMainBuffer().availableForGet(id_) < bytesToGet)
+    if (Manager::instance().getMainBuffer().availableForGet(id_) < samplesToGet)
         return 0;
 
-    SFLDataFormat *micData = audioRtpRecord_.decData_.data();
-    const size_t bytes = Manager::instance().getMainBuffer().getData(micData, bytesToGet, id_);
+    AudioBuffer& micData = audioRtpRecord_.decData_;
+    micData.resize(samplesToGet);
+    const size_t samps = Manager::instance().getMainBuffer().getData(micData, id_);
 
 #ifdef RECTODISK
-    rtpNotResampled.write((const char *)micData, bytes);
+    rtpNotResampled << micData;
 #endif
 
-    if (bytes != bytesToGet) {
-        ERROR("Asked for %d bytes from mainbuffer, got %d", bytesToGet, bytes);
+    if (samps != samplesToGet) {
+        ERROR("Asked for %d samples from mainbuffer, got %d", samplesToGet, samps);
         return 0;
     }
 
-    int samples = bytesToGet / sizeof(SFLDataFormat);
-
-    audioRtpRecord_.fadeInDecodedData(samples);
+    audioRtpRecord_.fadeInDecodedData();
 
-    SFLDataFormat *out = micData;
+    AudioBuffer *out = &micData;
 
     if (codecSampleRate != mainBufferSampleRate) {
         RETURN_IF_NULL(audioRtpRecord_.converterEncode_, 0, "Converter already destroyed");
 
-        audioRtpRecord_.converterEncode_->resample(micData,
-                audioRtpRecord_.resampledData_.data(),
-                audioRtpRecord_.resampledData_.size(),
-                mainBufferSampleRate, codecSampleRate,
-                samplesToGet);
+        micData.setSampleRate(mainBufferSampleRate);
+        audioRtpRecord_.resampledData_.setSampleRate(codecSampleRate);
+        audioRtpRecord_.converterEncode_->resample(micData, audioRtpRecord_.resampledData_);
 
 #ifdef RECTODISK
-        rtpResampled.write((const char *)audioRtpRecord_.resampledData_.data(), samplesToGet*sizeof(SFLDataFormat)/2 );
+        rtpResampled << audioRtpRecord_.resampledData_;
 #endif
 
-        out = audioRtpRecord_.resampledData_.data();
+        out = &(audioRtpRecord_.resampledData_);
     }
 
 #if HAVE_SPEEXDSP
+
     if (Manager::instance().audioPreference.getNoiseReduce()) {
         ScopedLock lock(audioRtpRecord_.audioProcessMutex_);
         RETURN_IF_NULL(audioRtpRecord_.noiseSuppressEncode_, 0, "Noise suppressor already destroyed");
         audioRtpRecord_.noiseSuppressEncode_->process(micData, getCodecFrameSize());
     }
+
+#endif
+
+#ifdef RTP_ENCODE_RECTODISK
+    beforesend.write((const char *)(micData), getCodecFrameSize() * 2);
 #endif
 
     {
         ScopedLock lock(audioRtpRecord_.audioCodecMutex_);
         RETURN_IF_NULL(audioRtpRecord_.getCurrentCodec(), 0, "Audio codec already destroyed");
         unsigned char *micDataEncoded = audioRtpRecord_.encodedData_.data();
-        return audioRtpRecord_.getCurrentCodec()->encode(micDataEncoded, out, getCodecFrameSize());
+        return audioRtpRecord_.getCurrentCodec()->encode(micDataEncoded, out->getData(), getCodecFrameSize());
     }
 }
 #undef RETURN_IF_NULL
@@ -347,70 +359,74 @@ void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, size_t si
 {
     if (audioRtpRecord_.isDead())
         return;
+
     if (audioRtpRecord_.decoderPayloadType_ != payloadType) {
         const bool switched = audioRtpRecord_.tryToSwitchPayloadTypes(payloadType);
+
         if (not switched) {
             if (!warningInterval_) {
                 warningInterval_ = 250;
                 WARN("Invalid payload type %d, expected %d", payloadType, audioRtpRecord_.decoderPayloadType_);
             }
+
             warningInterval_--;
             return;
         }
     }
 
-    int inSamples = 0;
-    size = std::min(size, audioRtpRecord_.decData_.size());
-    SFLDataFormat *spkrDataDecoded = audioRtpRecord_.decData_.data();
+    size = std::min(size, audioRtpRecord_.decData_.samples());
+
     {
         ScopedLock lock(audioRtpRecord_.audioCodecMutex_);
         RETURN_IF_NULL(audioRtpRecord_.getCurrentCodec(), "Audio codecs already destroyed");
         // Return the size of data in samples
-        inSamples = audioRtpRecord_.getCurrentCodec()->decode(spkrDataDecoded, spkrData, size);
+        audioRtpRecord_.getCurrentCodec()->decode(audioRtpRecord_.decData_.getData(), spkrData, size);
     }
 
+#ifdef RTP_DECODE_RECTODISK
+    afterdecode.write((const char *)spkrDataDecoded, inSamples * sizeof(SFLDataFormat));
+#endif
+#undef RTP_DECODE_RECTODISK
+
 #if HAVE_SPEEXDSP
+
     if (Manager::instance().audioPreference.getNoiseReduce()) {
         ScopedLock lock(audioRtpRecord_.audioProcessMutex_);
         RETURN_IF_NULL(audioRtpRecord_.noiseSuppressDecode_, "Noise suppressor already destroyed");
-        audioRtpRecord_.noiseSuppressDecode_->process(spkrDataDecoded, getCodecFrameSize());
+        audioRtpRecord_.noiseSuppressDecode_->process(audioRtpRecord_.decData_, getCodecFrameSize());
     }
+
 #endif
 
-    audioRtpRecord_.fadeInDecodedData(inSamples);
+    audioRtpRecord_.fadeInDecodedData();
 
-    // Normalize incomming signal
-    gainController_.process(spkrDataDecoded, inSamples);
+    // Normalize incoming signal
+    gainController_.process(audioRtpRecord_.decData_);
 
-    SFLDataFormat *out = spkrDataDecoded;
-    int outSamples = inSamples;
+    AudioBuffer *out = &(audioRtpRecord_.decData_);
 
-    int codecSampleRate = getCodecSampleRate();
+    int codecSampleRate = out->getSampleRate();
     int mainBufferSampleRate = Manager::instance().getMainBuffer().getInternalSamplingRate();
 
     // test if resampling is required
     if (codecSampleRate != mainBufferSampleRate) {
         RETURN_IF_NULL(audioRtpRecord_.converterDecode_, "Converter already destroyed");
-        out = audioRtpRecord_.resampledData_.data();
+        out = &(audioRtpRecord_.resampledData_);
         // Do sample rate conversion
-        outSamples = ((float) inSamples * ((float) mainBufferSampleRate / (float) codecSampleRate));
-        audioRtpRecord_.converterDecode_->resample(spkrDataDecoded, out,
-                audioRtpRecord_.resampledData_.size(), codecSampleRate,
-                mainBufferSampleRate, inSamples);
+        audioRtpRecord_.converterDecode_->resample(audioRtpRecord_.decData_, audioRtpRecord_.resampledData_);
     }
 
-    Manager::instance().getMainBuffer().putData(out, outSamples * sizeof(SFLDataFormat), id_);
+    Manager::instance().getMainBuffer().putData(*out, id_);
 }
 #undef RETURN_IF_NULL
 
-void AudioRtpRecord::fadeInDecodedData(size_t size)
+void AudioRtpRecord::fadeInDecodedData()
 {
     // if factor reaches 1, this function should have no effect
-    if (fadeFactor_ >= 1.0 or size > decData_.size())
+    if (fadeFactor_ >= 1.0)
         return;
 
-    for (size_t i = 0; i < size; ++i)
-        decData_[i] *= fadeFactor_;
+    decData_.applyGain(fadeFactor_);
 
     // Factor used to increase volume in fade in
     const double FADEIN_STEP_SIZE = 4.0;
@@ -421,17 +437,24 @@ bool
 AudioRtpRecordHandler::codecsDiffer(const std::vector<AudioCodec*> &codecs) const
 {
     const std::vector<AudioCodec*> &current = audioRtpRecord_.audioCodecs_;
+
     if (codecs.size() != current.size())
         return true;
-    for (std::vector<AudioCodec*>::const_iterator i = codecs.begin(); i != codecs.end(); ++i) {
-        if (*i) {
-            bool matched = false;
-            for (std::vector<AudioCodec*>::const_iterator j = current.begin(); !matched and j != current.end(); ++j)
-                matched = (*i)->getPayloadType() == (*j)->getPayloadType();
-            if (not matched)
-                return true;
-        }
+
+    for (const auto &i : codecs) {
+        if (!i)
+            continue;
+
+        bool matched = false;
+
+        for (const auto &j : current)
+            if ((matched = i->getPayloadType() == j->getPayloadType()))
+                break;
+
+        if (not matched)
+            return true;
     }
+
     return false;
 }
 
diff --git a/daemon/src/audio/audiortp/audio_rtp_record_handler.h b/daemon/src/audio/audiortp/audio_rtp_record_handler.h
index 18ec89ae9e393644b3be618ce8bc915782374d4f..af6232f70f2bd7e17742a5ebd342e6a5699b2528 100644
--- a/daemon/src/audio/audiortp/audio_rtp_record_handler.h
+++ b/daemon/src/audio/audiortp/audio_rtp_record_handler.h
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
  *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *  Author: Adrien Beraud <adrien.beraud@wisdomvibes.com>
  *
  *  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
@@ -94,9 +95,8 @@ class AudioRtpRecord {
         int encoderPayloadType_;
         int decoderPayloadType_;
         bool hasDynamicPayloadType_;
-        std::tr1::array<SFLDataFormat, DEC_BUFFER_SIZE> decData_;
-// FIXME: resampledData should be resized as needed
-        std::tr1::array<SFLDataFormat, DEC_BUFFER_SIZE * 4> resampledData_;
+        AudioBuffer decData_;
+        AudioBuffer resampledData_;
         std::tr1::array<unsigned char, DEC_BUFFER_SIZE> encodedData_;
         SamplerateConverter *converterEncode_;
         SamplerateConverter *converterDecode_;
@@ -117,7 +117,7 @@ class AudioRtpRecord {
         /**
         * Ramp In audio data to avoid audio click from peer
         */
-        void fadeInDecodedData(size_t size);
+        void fadeInDecodedData();//size_t size);
         NON_COPYABLE(AudioRtpRecord);
 #ifdef CCPP_PREFIX
         ost::AtomicCounter dead_;
diff --git a/daemon/src/audio/audiortp/audio_rtp_session.cpp b/daemon/src/audio/audiortp/audio_rtp_session.cpp
index ab0fff684a992b61f715ab4228fdfd6fcce6f697..04bce53c96e37413917de5e9bfe566a781dbe191 100644
--- a/daemon/src/audio/audiortp/audio_rtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_session.cpp
@@ -71,11 +71,13 @@ void AudioRtpSession::updateSessionMedia(const std::vector<AudioCodec*> &audioCo
     Manager::instance().audioSamplingRateChanged(audioRtpRecord_.codecSampleRate_);
 
 #if HAVE_SPEEXDSP
+
     if (lastSamplingRate != audioRtpRecord_.codecSampleRate_) {
         DEBUG("Update noise suppressor with sampling rate %d and frame size %d",
               getCodecSampleRate(), getCodecFrameSize());
         initNoiseSuppress();
     }
+
 #endif
 }
 
@@ -85,6 +87,7 @@ void AudioRtpSession::setSessionMedia(const std::vector<AudioCodec*> &audioCodec
 
     // G722 requires timestamp to be incremented at 8kHz
     const ost::PayloadType payloadType = getEncoderPayloadType();
+
     if (payloadType == ost::sptG722) {
         const int G722_RTP_TIME_INCREMENT = 160;
         timestampIncrement_ = G722_RTP_TIME_INCREMENT;
@@ -93,7 +96,7 @@ void AudioRtpSession::setSessionMedia(const std::vector<AudioCodec*> &audioCodec
 
     if (payloadType == ost::sptG722) {
         const int G722_RTP_CLOCK_RATE = 8000;
-        queue_.setPayloadFormat(ost::DynamicPayloadFormat( payloadType, G722_RTP_CLOCK_RATE));
+        queue_.setPayloadFormat(ost::DynamicPayloadFormat(payloadType, G722_RTP_CLOCK_RATE));
     } else {
         if (getHasDynamicPayload())
             queue_.setPayloadFormat(ost::DynamicPayloadFormat(payloadType, getCodecSampleRate()));
@@ -125,7 +128,8 @@ void AudioRtpSession::sendDtmfEvent()
     // Set marker in case this is a new Event
     if (dtmf.newevent)
         queue_.setMark(true);
-    queue_.sendImmediate(timestamp_, (const unsigned char *) (& (dtmf.payload)), sizeof (ost::RTPPacket::RFC2833Payload));
+
+    queue_.sendImmediate(timestamp_, (const unsigned char *)(& (dtmf.payload)), sizeof(ost::RTPPacket::RFC2833Payload));
 
     // This is no longer a new event
     if (dtmf.newevent) {
@@ -140,9 +144,11 @@ void AudioRtpSession::sendDtmfEvent()
     // decrease length remaining to process for this event
     dtmf.length -= increment;
     dtmf.payload.duration++;
+
     // next packet is going to be the last one
     if ((dtmf.length - increment) < increment)
         dtmf.payload.ebit = true;
+
     if (dtmf.length < increment)
         audioRtpRecord_.dtmfQueue_.pop_front();
 }
@@ -200,7 +206,7 @@ void AudioRtpSession::setDestinationIpAddress()
 
     if (!remote_ip_) {
         WARN("Target IP address (%s) is not correct!",
-              call_.getLocalSDP()->getRemoteIP().data());
+             call_.getLocalSDP()->getRemoteIP().data());
         return;
     }
 
@@ -276,6 +282,7 @@ AudioRtpSession::AudioRtpSendThread::AudioRtpSendThread(AudioRtpSession &session
 AudioRtpSession::AudioRtpSendThread::~AudioRtpSendThread()
 {
     running_ = false;
+
     if (thread_)
         pthread_join(thread_, NULL);
 }
diff --git a/daemon/src/audio/audiortp/audio_srtp_session.cpp b/daemon/src/audio/audiortp/audio_srtp_session.cpp
index cdf219abd5d660cad1897e7ff4e14d3035e86f01..a7ad99e885d478802793e6d547951187a88d607e 100644
--- a/daemon/src/audio/audiortp/audio_srtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_srtp_session.cpp
@@ -47,84 +47,84 @@
 namespace sfl {
 
 namespace {
-    std::string
-    encodeBase64(unsigned char *input, int length)
-    {
-        // init decoder
-        BIO *b64 = BIO_new(BIO_f_base64());
-        BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+std::string
+encodeBase64(unsigned char *input, int length)
+{
+    // init decoder
+    BIO *b64 = BIO_new(BIO_f_base64());
+    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
 
-        // init internal buffer
-        BIO *bmem = BIO_new(BIO_s_mem());
+    // init internal buffer
+    BIO *bmem = BIO_new(BIO_s_mem());
 
-        // create decoder chain
-        b64 = BIO_push(b64, bmem);
+    // create decoder chain
+    b64 = BIO_push(b64, bmem);
 
-        BIO_write(b64, input, length);
-        // BIO_flush (b64);
+    BIO_write(b64, input, length);
+    // BIO_flush (b64);
 
-        // get pointer to data
-        BUF_MEM *bptr = 0;
-        BIO_get_mem_ptr(b64, &bptr);
+    // get pointer to data
+    BUF_MEM *bptr = 0;
+    BIO_get_mem_ptr(b64, &bptr);
 
-        std::string output(bptr->data, bptr->length);
+    std::string output(bptr->data, bptr->length);
 
-        BIO_free_all(bmem);
+    BIO_free_all(bmem);
 
-        return output;
-    }
+    return output;
+}
 
-    std::vector<char> decodeBase64(unsigned char *input, int length)
-    {
-        BIO *b64, *bmem;
+std::vector<char> decodeBase64(unsigned char *input, int length)
+{
+    BIO *b64, *bmem;
 
-        // init decoder and read-only BIO buffer
-        b64 = BIO_new(BIO_f_base64());
-        BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+    // init decoder and read-only BIO buffer
+    b64 = BIO_new(BIO_f_base64());
+    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
 
-        // init internal buffer
-        bmem = BIO_new_mem_buf(input, length);
+    // init internal buffer
+    bmem = BIO_new_mem_buf(input, length);
 
-        // create encoder chain
-        bmem = BIO_push(b64, bmem);
+    // create encoder chain
+    bmem = BIO_push(b64, bmem);
 
-        std::vector<char> buffer(length, 0);
-        BIO_read(bmem, &(*buffer.begin()), length);
+    std::vector<char> buffer(length, 0);
+    BIO_read(bmem, buffer.data(), length);
 
-        BIO_free_all(bmem);
+    BIO_free_all(bmem);
 
-        return buffer;
-    }
+    return buffer;
+}
 
-    // Fills the array dest with length random bytes
-    void bufferFillMasterKey(std::vector<uint8>& dest)
-    {
-        DEBUG("Init local master key");
+// Fills the array dest with length random bytes
+void bufferFillMasterKey(std::vector<uint8>& dest)
+{
+    DEBUG("Init local master key");
 
-        // Allocate memory for key
-        std::vector<unsigned char> random_key(dest.size());
+    // Allocate memory for key
+    std::vector<unsigned char> random_key(dest.size());
 
-        // Generate ryptographically strong pseudo-random bytes
-        if (RAND_bytes(&(*random_key.begin()), dest.size()) != 1)
-            DEBUG("Error occured while generating cryptographically strong pseudo-random key");
+    // Generate ryptographically strong pseudo-random bytes
+    if (RAND_bytes(random_key.data(), dest.size()) != 1)
+        DEBUG("Error occured while generating cryptographically strong pseudo-random key");
 
-        std::copy(random_key.begin(), random_key.end(), dest.begin());
-    }
+    std::copy(random_key.begin(), random_key.end(), dest.begin());
+}
 
-    // Fills the array dest with length random bytes
-    void bufferFillMasterSalt(std::vector<uint8>& dest)
-    {
-        DEBUG("Init local master key");
+// Fills the array dest with length random bytes
+void bufferFillMasterSalt(std::vector<uint8>& dest)
+{
+    DEBUG("Init local master key");
 
-        // Allocate memory for key
-        std::vector<unsigned char> random_key(dest.size());
+    // Allocate memory for key
+    std::vector<unsigned char> random_key(dest.size());
 
-        // Generate ryptographically strong pseudo-random bytes
-        if (RAND_bytes(&(*random_key.begin()), dest.size()) != 1)
-            DEBUG("Error occured while generating cryptographically strong pseudo-random key");
+    // Generate ryptographically strong pseudo-random bytes
+    if (RAND_bytes(random_key.data(), dest.size()) != 1)
+        DEBUG("Error occured while generating cryptographically strong pseudo-random key");
 
-        std::copy(random_key.begin(), random_key.end(), dest.begin());
-    }
+    std::copy(random_key.begin(), random_key.end(), dest.begin());
+}
 }
 
 AudioSrtpSession::AudioSrtpSession(SIPCall &call) :
@@ -213,6 +213,7 @@ void AudioSrtpSession::setRemoteCryptoInfo(const sfl::SdesNegotiator& nego)
 
         // init crypto content in Srtp session
         initializeRemoteCryptoContext();
+
         if (remoteCryptoCtx_) {
             setInQueueCryptoContext(remoteCryptoCtx_);
         }
@@ -222,7 +223,7 @@ void AudioSrtpSession::setRemoteCryptoInfo(const sfl::SdesNegotiator& nego)
 }
 
 namespace {
-    static const size_t BITS_PER_BYTE = 8;
+static const size_t BITS_PER_BYTE = 8;
 }
 
 void AudioSrtpSession::initializeLocalMasterKey()
@@ -250,7 +251,7 @@ std::string AudioSrtpSession::getBase64ConcatenatedKeys()
     concatKeys.insert(concatKeys.end(), localMasterSalt_.begin(), localMasterSalt_.end());
 
     // encode concatenated keys in base64
-    return encodeBase64(&(*concatKeys.begin()), concatKeys.size());
+    return encodeBase64(concatKeys.data(), concatKeys.size());
 }
 
 void AudioSrtpSession::unBase64ConcatenatedKeys(std::string base64keys)
@@ -277,18 +278,18 @@ void AudioSrtpSession::initializeRemoteCryptoContext()
     const CryptoSuiteDefinition &crypto = sfl::CryptoSuites[remoteCryptoSuite_];
 
     remoteCryptoCtx_ = new ost::CryptoContext(0x0,
-                                              0,    // roc,
-                                              0L,   // keydr,
-                                              SrtpEncryptionAESCM,
-                                              SrtpAuthenticationSha1Hmac,
-                                              &(*remoteMasterKey_.begin()),
-                                              remoteMasterKey_.size(),
-                                              &(*remoteMasterSalt_.begin()),
-                                              remoteMasterSalt_.size(),
-                                              crypto.encryptionKeyLength / BITS_PER_BYTE,
-                                              crypto.srtpAuthKeyLength / BITS_PER_BYTE,
-                                              crypto.masterSaltLength / BITS_PER_BYTE,
-                                              crypto.srtpAuthTagLength / BITS_PER_BYTE);
+            0,    // roc,
+            0L,   // keydr,
+            SrtpEncryptionAESCM,
+            SrtpAuthenticationSha1Hmac,
+            remoteMasterKey_.data(),
+            remoteMasterKey_.size(),
+            remoteMasterSalt_.data(),
+            remoteMasterSalt_.size(),
+            crypto.encryptionKeyLength / BITS_PER_BYTE,
+            crypto.srtpAuthKeyLength / BITS_PER_BYTE,
+            crypto.masterSaltLength / BITS_PER_BYTE,
+            crypto.srtpAuthTagLength / BITS_PER_BYTE);
 
 }
 
@@ -299,18 +300,18 @@ void AudioSrtpSession::initializeLocalCryptoContext()
     const CryptoSuiteDefinition &crypto = sfl::CryptoSuites[localCryptoSuite_];
 
     localCryptoCtx_ = new ost::CryptoContext(OutgoingDataQueue::getLocalSSRC(),
-                                             0,     // roc,
-                                             0L,    // keydr,
-                                             SrtpEncryptionAESCM,
-                                             SrtpAuthenticationSha1Hmac,
-                                             &(*localMasterKey_.begin()),
-                                             localMasterKey_.size(),
-                                             &(*localMasterSalt_.begin()),
-                                             localMasterSalt_.size(),
-                                             crypto.encryptionKeyLength / BITS_PER_BYTE,
-                                             crypto.srtpAuthKeyLength / BITS_PER_BYTE,
-                                             crypto.masterSaltLength / BITS_PER_BYTE,
-                                             crypto.srtpAuthTagLength / BITS_PER_BYTE);
+            0,     // roc,
+            0L,    // keydr,
+            SrtpEncryptionAESCM,
+            SrtpAuthenticationSha1Hmac,
+            localMasterKey_.data(),
+            localMasterKey_.size(),
+            localMasterSalt_.data(),
+            localMasterSalt_.size(),
+            crypto.encryptionKeyLength / BITS_PER_BYTE,
+            crypto.srtpAuthKeyLength / BITS_PER_BYTE,
+            crypto.masterSaltLength / BITS_PER_BYTE,
+            crypto.srtpAuthTagLength / BITS_PER_BYTE);
 }
 
 void
diff --git a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
index 31850866d4f0c2f923e967a5df59f355a8e179cb..48e8048e7f7dcc6d61735d6c2812843445bef6f8 100644
--- a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
@@ -43,7 +43,7 @@ AudioSymmetricRtpSession::AudioSymmetricRtpSession(SIPCall &call) :
     , AudioRtpSession(call, *this)
 {
     DEBUG("Setting new RTP session with destination %s:%d",
-            call_.getLocalIp().c_str(), call_.getLocalAudioPort());
+          call_.getLocalIp().c_str(), call_.getLocalAudioPort());
     audioRtpRecord_.callId_ = call_.getCallId();
 }
 
diff --git a/daemon/src/audio/audiortp/zrtp_session_callback.cpp b/daemon/src/audio/audiortp/zrtp_session_callback.cpp
index 3f26698d6d320147948988610f8afed8b3f66502..4106c7401d25c5935336d61a4ae20f45100b1614 100644
--- a/daemon/src/audio/audiortp/zrtp_session_callback.cpp
+++ b/daemon/src/audio/audiortp/zrtp_session_callback.cpp
@@ -30,8 +30,8 @@
 #include "zrtp_session_callback.h"
 #include "logger.h"
 #include "sip/sipcall.h"
-#include "dbus/dbusmanager.h"
-#include "dbus/callmanager.h"
+#include "client/client.h"
+#include "client/callmanager.h"
 #include "manager.h"
 
 #include <cstdlib>
@@ -104,28 +104,28 @@ void
 ZrtpSessionCallback::secureOn(std::string cipher)
 {
     DEBUG("Secure mode is on with cipher %s", cipher.c_str());
-    Manager::instance().getDbusManager()->getCallManager()->secureZrtpOn(call_.getCallId(), cipher);
+    Manager::instance().getClient()->getCallManager()->secureZrtpOn(call_.getCallId(), cipher);
 }
 
 void
 ZrtpSessionCallback::secureOff()
 {
     DEBUG("Secure mode is off");
-    Manager::instance().getDbusManager()->getCallManager()->secureZrtpOff(call_.getCallId());
+    Manager::instance().getClient()->getCallManager()->secureZrtpOff(call_.getCallId());
 }
 
 void
 ZrtpSessionCallback::showSAS(std::string sas, bool verified)
 {
     DEBUG("SAS is: %s", sas.c_str());
-    Manager::instance().getDbusManager()->getCallManager()->showSAS(call_.getCallId(), sas, verified);
+    Manager::instance().getClient()->getCallManager()->showSAS(call_.getCallId(), sas, verified);
 }
 
 void
 ZrtpSessionCallback::zrtpNotSuppOther()
 {
     DEBUG("Callee does not support ZRTP");
-    Manager::instance().getDbusManager()->getCallManager()->zrtpNotSuppOther(call_.getCallId());
+    Manager::instance().getClient()->getCallManager()->zrtpNotSuppOther(call_.getCallId());
 }
 
 void
@@ -151,15 +151,17 @@ ZrtpSessionCallback::zrtpNegotiationFailed(MessageSeverity severity, int subCode
             DEBUG("Sent error packet: ");
 
         std::map<int32, std::string>::const_iterator iter = zrtpMap_.find(subCode);
+
         if (iter != zrtpMap_.end()) {
             DEBUG("%s", iter->second.c_str());
-            Manager::instance().getDbusManager()->getCallManager()->zrtpNegotiationFailed(call_.getCallId(), iter->second, "ZRTP");
+            Manager::instance().getClient()->getCallManager()->zrtpNegotiationFailed(call_.getCallId(), iter->second, "ZRTP");
         }
     } else {
         std::map<int32, std::string>::const_iterator iter = severeMap_.find(subCode);
+
         if (iter != severeMap_.end()) {
             DEBUG("%s", iter->second.c_str());
-            Manager::instance().getDbusManager()->getCallManager()->zrtpNegotiationFailed(call_.getCallId(), iter->second, "severe");
+            Manager::instance().getClient()->getCallManager()->zrtpNegotiationFailed(call_.getCallId(), iter->second, "severe");
         }
     }
 }
@@ -168,7 +170,7 @@ void
 ZrtpSessionCallback::confirmGoClear()
 {
     DEBUG("Received go clear message. Until confirmation, ZRTP won't send any data");
-    Manager::instance().getDbusManager()->getCallManager()->zrtpNotSuppOther(call_.getCallId());
+    Manager::instance().getClient()->getCallManager()->zrtpNotSuppOther(call_.getCallId());
 }
 
 std::map<int32, std::string> ZrtpSessionCallback::infoMap_;
diff --git a/daemon/src/audio/codecs/alaw.cpp b/daemon/src/audio/codecs/alaw.cpp
index 18ea89033aec8eed0f63bbac58e130d6cae476bc..55ea59d206af82c3627c546890195d3eae6f2c82 100644
--- a/daemon/src/audio/codecs/alaw.cpp
+++ b/daemon/src/audio/codecs/alaw.cpp
@@ -42,7 +42,7 @@ class Alaw : public sfl::AudioCodec {
         }
 
     private:
-        int decode(SFLDataFormat *dst, unsigned char *src, size_t buf_size)
+        int decode(SFLAudioSample *dst, unsigned char *src, size_t buf_size)
         {
             for (unsigned char* end = src + buf_size; src < end; ++src, ++dst)
                 *dst = ALawDecode(*src);
@@ -50,7 +50,7 @@ class Alaw : public sfl::AudioCodec {
             return buf_size;
         }
 
-        int encode(unsigned char *dst, SFLDataFormat *src, size_t buf_size)
+        int encode(unsigned char *dst, SFLAudioSample *src, size_t buf_size)
         {
             for (unsigned char *end = dst + buf_size; dst < end; ++src, ++dst)
                 *dst = ALawEncode(*src);
@@ -58,10 +58,9 @@ class Alaw : public sfl::AudioCodec {
             return buf_size;
         }
 
-        int ALawDecode(uint8 alaw)
-        {
+        int ALawDecode(uint8_t alaw) {
             alaw ^= 0x55;  // A-law has alternate bits inverted for transmission
-            uint sign = alaw & 0x80;
+            uint8_t sign = alaw & 0x80;
             int linear = alaw & 0x1f;
             linear <<= 4;
             linear += 8;  // Add a 'half' bit (0x08) to place PCM value in middle of range
@@ -70,7 +69,7 @@ class Alaw : public sfl::AudioCodec {
 
             if (alaw >= 0x20) {
                 linear |= 0x100;  // Put in MSB
-                uint shift = (alaw >> 4) - 1;
+                uint8_t shift = (alaw >> 4) - 1;
                 linear <<= shift;
             }
 
@@ -80,10 +79,9 @@ class Alaw : public sfl::AudioCodec {
                 return linear;
         }
 
-        uint8 ALawEncode(SFLDataFormat pcm16)
-        {
+        uint8_t ALawEncode(SFLAudioSample pcm16) {
             int p = pcm16;
-            uint a;  // u-law value we are forming
+            uint8_t a;  // u-law value we are forming
 
             if (p < 0) {
                 p = ~p;
diff --git a/daemon/src/audio/codecs/audiocodec.cpp b/daemon/src/audio/codecs/audiocodec.cpp
index 94d7927052352551c70185c5d4983f31b6e57a6f..6bfaa963b66bfb6de0021de672dc0e6ffb793368 100644
--- a/daemon/src/audio/codecs/audiocodec.cpp
+++ b/daemon/src/audio/codecs/audiocodec.cpp
@@ -32,19 +32,17 @@
 
 #include "audiocodec.h"
 using std::ptrdiff_t;
-#include <ccrtp/rtp.h>
 
 namespace sfl {
 
-AudioCodec::AudioCodec(uint8 payload, const std::string &codecName,
-                       int clockRate, int frameSize, int channel) :
+AudioCodec::AudioCodec(uint8_t payload, const std::string &codecName,
+                       int clockRate, int frameSize, unsigned channels) :
     codecName_(codecName),
     clockRate_(clockRate),
-    channel_(channel),
+    channel_(channels),
     frameSize_(frameSize),
     bitrate_(0.0),
     payload_(payload),
-    payloadFormat_(payload, clockRate_),
     hasDynamicPayload_((payload_ >= 96 and payload_ <= 127) or payload_ == 9)
 {}
 
@@ -55,16 +53,27 @@ AudioCodec::AudioCodec(const AudioCodec& c) :
     frameSize_(c.frameSize_),
     bitrate_(c.bitrate_),
     payload_(c.payload_),
-    payloadFormat_(c.payloadFormat_),
     hasDynamicPayload_(c.hasDynamicPayload_)
 {}
 
+// Mono only, subclasses must implement multichannel support
+int AudioCodec::decode(std::vector<std::vector<SFLAudioSample> > &dst, unsigned char *buf, size_t buffer_size)
+{
+    return decode(dst[0].data(), buf, buffer_size);
+}
+
+// Mono only, subclasses must implement multichannel support
+int AudioCodec::encode(unsigned char *dst, std::vector<std::vector<SFLAudioSample> > &src, size_t buffer_size)
+{
+    return encode(dst, src[0].data(), buffer_size);
+}
+
 std::string AudioCodec::getMimeSubtype() const
 {
     return codecName_;
 }
 
-uint8 AudioCodec::getPayloadType() const
+uint8_t AudioCodec::getPayloadType() const
 {
     return payload_;
 }
@@ -74,7 +83,7 @@ bool AudioCodec::hasDynamicPayload() const
     return hasDynamicPayload_;
 }
 
-uint32 AudioCodec::getClockRate() const
+uint32_t AudioCodec::getClockRate() const
 {
     return clockRate_;
 }
@@ -89,4 +98,9 @@ double AudioCodec::getBitRate() const
     return bitrate_;
 }
 
+unsigned AudioCodec::getChannels() const
+{
+    return channel_;
+}
+
 } // end namespace sfl
diff --git a/daemon/src/audio/codecs/audiocodec.h b/daemon/src/audio/codecs/audiocodec.h
index 7ed273101a4ef069b262233e9bcc8bc348c3cee5..a45910a6543fb1f58e4a8b6e1fa139c4cf218ba8 100644
--- a/daemon/src/audio/codecs/audiocodec.h
+++ b/daemon/src/audio/codecs/audiocodec.h
@@ -33,8 +33,8 @@
 #define __AUDIO_CODEC_H__
 
 #include <string>
-#include "cc_config.h"
-#include <ccrtp/formats.h> // for ost::DynamicPayloadFormat
+#include <vector>
+#include "sfl_types.h"
 
 #define XSTR(s) STR(s)
 #define STR(s) #s
@@ -52,8 +52,7 @@ namespace sfl {
 
 class AudioCodec {
     public:
-        AudioCodec(uint8 payload, const std::string &codecName, int clockRate,
-                   int frameSize, int channel);
+        AudioCodec(uint8_t payload, const std::string &codecName, int clockRate, int frameSize, unsigned channels);
 
         /**
          * Copy constructor.
@@ -69,18 +68,30 @@ class AudioCodec {
          * @param buffer_size : the size of the input buffer
          * @return the number of samples decoded
          */
-        virtual int decode(short *dst, unsigned char *buf, size_t buffer_size) = 0;
+        virtual int decode(SFLAudioSample *dst, unsigned char *buf, size_t buffer_size) = 0;
 
         /**
          * Encode an input buffer and fill the output buffer with the encoded data
          * @param buffer_size : the maximum size of encoded data buffer (dst)
          * @return the number of bytes encoded
          */
-        virtual int encode(unsigned char *dst, short *src, size_t buffer_size) = 0;
+        virtual int encode(unsigned char *dst, SFLAudioSample *src, size_t buffer_size) = 0;
 
-        uint8 getPayloadType() const;
+        /**
+         * Multichannel version of decode().
+         * Default implementation decode(short *, unsigned char *, size_t) to the first channel (assume 1 channel).
+         */
+        virtual int decode(std::vector<std::vector<SFLAudioSample> > &dst, unsigned char *buf, size_t buffer_size);
+
+        /**
+         * Multichannel version of encode().
+         * Default implementation calls encode() on the first channel (assume 1 channel).
+         */
+        virtual int encode(unsigned char *dst, std::vector<std::vector<SFLAudioSample> > &src, size_t buffer_size);
+
+        uint8_t getPayloadType() const;
 
-        void setPayloadType(uint8 pt) {
+        void setPayloadType(uint8_t pt) {
             payload_ = pt;
         }
 
@@ -89,10 +100,12 @@ class AudioCodec {
          */
         bool hasDynamicPayload() const;
 
-        uint32 getClockRate() const;
+        uint32_t getClockRate() const;
 
         double getBitRate() const;
 
+        unsigned getChannels() const;
+
         /**
          * @return the framing size for this codec.
          */
@@ -103,10 +116,10 @@ class AudioCodec {
         std::string codecName_; // what we put inside sdp
 
         /** Clock rate or sample rate of the codec, in Hz */
-        uint32 clockRate_;
+        uint32_t clockRate_;
 
         /** Number of channel 1 = mono, 2 = stereo */
-        uint8 channel_;
+        uint8_t channel_;
 
         /** codec frame size in samples*/
         unsigned frameSize_;
@@ -116,9 +129,7 @@ class AudioCodec {
 
     private:
         AudioCodec& operator=(const AudioCodec&);
-        uint8 payload_;
-
-        ost::DynamicPayloadFormat payloadFormat_;
+        uint8_t payload_;
 
 protected:
         bool hasDynamicPayload_;
diff --git a/daemon/src/audio/codecs/audiocodecfactory.cpp b/daemon/src/audio/codecs/audiocodecfactory.cpp
index fc1319db585ab73f2ece4d113a8a83dc05a4f9d7..5f753cbf7d10c9d704ae75bf1e5bb55d5e8889c2 100644
--- a/daemon/src/audio/codecs/audiocodecfactory.cpp
+++ b/daemon/src/audio/codecs/audiocodecfactory.cpp
@@ -56,10 +56,9 @@ AudioCodecFactory::AudioCodecFactory() :
     if (codecDynamicList.empty())
         ERROR("No codecs available");
     else {
-        for (AudioCodecVector::const_iterator iter = codecDynamicList.begin();
-                iter != codecDynamicList.end() ; ++iter) {
-            codecsMap_[(int)(*iter)->getPayloadType()] = *iter;
-            DEBUG("Loaded codec %s" , (*iter)->getMimeSubtype().c_str());
+        for (const auto &codec: codecDynamicList) {
+            codecsMap_[(int) codec->getPayloadType()] = codec;
+            DEBUG("Loaded codec %s" , codec->getMimeSubtype().c_str());
         }
     }
 }
@@ -68,8 +67,9 @@ void
 AudioCodecFactory::setDefaultOrder()
 {
     defaultCodecList_.clear();
-    for (AudioCodecsMap::const_iterator i = codecsMap_.begin(); i != codecsMap_.end(); ++i)
-        defaultCodecList_.push_back(i->first);
+
+    for (const auto &codec : codecsMap_)
+        defaultCodecList_.push_back(codec.first);
 }
 
 std::string
@@ -87,9 +87,10 @@ std::vector<int32_t>
 AudioCodecFactory::getCodecList() const
 {
     std::vector<int32_t> list;
-    for (AudioCodecsMap::const_iterator iter = codecsMap_.begin(); iter != codecsMap_.end(); ++iter)
-        if (iter->second)
-            list.push_back((int32_t) iter->first);
+
+    for (const auto &codec : codecsMap_)
+        if (codec.second)
+            list.push_back((int32_t) codec.first);
 
     return list;
 }
@@ -130,6 +131,17 @@ AudioCodecFactory::getSampleRate(int payload) const
         return 0;
 }
 
+unsigned
+AudioCodecFactory::getChannels(int payload) const
+{
+    AudioCodecsMap::const_iterator iter = codecsMap_.find(payload);
+
+    if (iter != codecsMap_.end())
+        return iter->second->getChannels();
+    else
+        return 0;
+}
+
 void
 AudioCodecFactory::saveActiveCodecs(const std::vector<std::string>& list)
 {
@@ -137,8 +149,8 @@ AudioCodecFactory::saveActiveCodecs(const std::vector<std::string>& list)
     // list contains the ordered payload of active codecs picked by the user
     // we used the codec vector to save the order.
 
-    for (std::vector<std::string>::const_iterator iter = list.begin(); iter != list.end(); ++iter) {
-        int payload = std::atoi(iter->c_str());
+    for (const auto &codec : list) {
+        int payload = std::atoi(codec.c_str());
 
         if (isCodecLoaded(payload))
             defaultCodecList_.push_back(static_cast<int>(payload));
@@ -148,9 +160,8 @@ AudioCodecFactory::saveActiveCodecs(const std::vector<std::string>& list)
 
 AudioCodecFactory::~AudioCodecFactory()
 {
-    for (std::vector<AudioCodecHandlePointer>::iterator iter =
-         codecInMemory_.begin(); iter != codecInMemory_.end(); ++iter)
-        unloadCodec(*iter);
+    for (auto &codec : codecInMemory_)
+        unloadCodec(codec);
 }
 
 std::vector<sfl::AudioCodec*>
@@ -168,8 +179,13 @@ AudioCodecFactory::scanCodecDirectory()
 
     const char *progDir = fileutils::get_program_dir();
 
-    if (progDir)
+    if (progDir) {
+#ifdef __ANDROID__
+        dirToScan.push_back(std::string(progDir) + DIR_SEPARATOR_STR + "lib/");
+#else
         dirToScan.push_back(std::string(progDir) + DIR_SEPARATOR_STR + "audio/codecs/");
+#endif
+	}
 
     for (size_t i = 0 ; i < dirToScan.size() ; i++) {
         std::string dirStr = dirToScan[i];
@@ -227,6 +243,7 @@ AudioCodecFactory::loadCodec(const std::string &path)
     }
 
     sfl::AudioCodec *a = static_cast<sfl::AudioCodec *>(createCodec());
+
     if (a)
         codecInMemory_.push_back(AudioCodecHandlePointer(a, codecHandle));
     else
@@ -240,6 +257,9 @@ void
 AudioCodecFactory::unloadCodec(AudioCodecHandlePointer &ptr)
 {
     destroy_t *destroyCodec = 0;
+    // flush last error
+    dlerror();
+
     if (ptr.second)
         destroyCodec = (destroy_t*) dlsym(ptr.second, "destroy");
 
@@ -260,19 +280,24 @@ AudioCodecFactory::unloadCodec(AudioCodecHandlePointer &ptr)
 sfl::AudioCodec*
 AudioCodecFactory::instantiateCodec(int payload) const
 {
-    std::vector<AudioCodecHandlePointer>::const_iterator iter;
+    // flush last error
+    dlerror();
 
     sfl::AudioCodec *result = NULL;
-    for (iter = codecInMemory_.begin(); iter != codecInMemory_.end(); ++iter) {
-        if (iter->first->getPayloadType() == payload) {
-            create_t* createCodec = (create_t*) dlsym(iter->second , AUDIO_CODEC_ENTRY_SYMBOL);
+
+    for (const auto &codec : codecInMemory_) {
+        if (codec.first->getPayloadType() == payload) {
+
+            create_t* createCodec = (create_t*) dlsym(codec.second , AUDIO_CODEC_ENTRY_SYMBOL);
 
             const char *error = dlerror();
 
-            if (error)
+            if (error) {
                 ERROR("%s", error);
-            else
+                dlerror();
+            } else {
                 result = static_cast<sfl::AudioCodec *>(createCodec());
+            }
         }
     }
 
@@ -284,7 +309,6 @@ AudioCodecFactory::seemsValid(const std::string &lib)
 {
     // The name of the shared library seems valid  <==> it looks like libcodec_xxx.so
     // We check this
-
     static const std::string prefix("libcodec_");
     static const std::string suffix(".so");
 
@@ -299,28 +323,31 @@ AudioCodecFactory::seemsValid(const std::string &lib)
         return false;
 
     static const std::string validCodecs[] = {
-    "ulaw",
-    "alaw",
-    "g722",
-    "g729", //G729 have to be loaded first, if it is valid or not is checked later
-    "opus", //Opus have to be loaded first, if it is valid or not is checked later
+        "ulaw",
+        "alaw",
+        "g722",
+        "g729", //G729 have to be loaded first, if it is valid or not is checked later
+        "opus", //Opus have to be loaded first, if it is valid or not is checked later
+        "opus_stereo",
 #ifdef HAVE_SPEEX_CODEC
-    "speex_nb",
-    "speex_wb",
-    "speex_ub",
+        "speex_nb",
+        "speex_wb",
+        "speex_ub",
 #endif
 
 #ifdef HAVE_GSM_CODEC
-    "gsm",
+        "gsm",
 #endif
 
 #ifdef BUILD_ILBC
-    "ilbc",
+        "ilbc",
 #endif
-    ""};
+        ""
+    };
 
     const std::string name(lib.substr(prefix.length(), len));
     const std::string *end = validCodecs + ARRAYSIZE(validCodecs);
+
     return find(validCodecs, end, name) != end;
 }
 
@@ -333,10 +360,8 @@ AudioCodecFactory::alreadyInCache(const std::string &lib)
 bool
 AudioCodecFactory::isCodecLoaded(int payload) const
 {
-    AudioCodecsMap::const_iterator iter;
-
-    for (iter = codecsMap_.begin(); iter != codecsMap_.end(); ++iter)
-        if (iter->first == payload)
+    for (const auto &codec : codecsMap_)
+        if (codec.first == payload)
             return true;
 
     return false;
@@ -359,6 +384,11 @@ AudioCodecFactory::getCodecSpecifications(const int32_t& payload) const
     // Add the bit rate
     ss << getBitRate(static_cast<int>(payload));
     v.push_back(ss.str());
+    ss.str("");
+
+    // Add the channel number
+    ss << getChannels(static_cast<int>(payload));
+    v.push_back(ss.str());
 
     return v;
 }
diff --git a/daemon/src/audio/codecs/audiocodecfactory.h b/daemon/src/audio/codecs/audiocodecfactory.h
index 137b7c2497254966a62a602bdd341c192b8add13..f7f4199fff863168985bf467a529fd69171ec4ad 100644
--- a/daemon/src/audio/codecs/audiocodecfactory.h
+++ b/daemon/src/audio/codecs/audiocodecfactory.h
@@ -87,6 +87,13 @@ class AudioCodecFactory {
          */
         int getSampleRate(int payload) const;
 
+        /**
+         * Get the number of channels of the specified codec
+         * @param payload The payload of the codec
+         * @return int The number of channels of the specified codec
+         */
+        unsigned getChannels(int payload) const;
+
         /**
          * Set the order of codecs by their payload
          * @param list The ordered list sent by DBus
diff --git a/daemon/src/audio/codecs/g722.cpp b/daemon/src/audio/codecs/g722.cpp
index 684766eb5bbc4aeb1bfa991a9061773a49bd21d8..8d25afde55ec54e3b265a7764f9e3564b34ae3cb 100644
--- a/daemon/src/audio/codecs/g722.cpp
+++ b/daemon/src/audio/codecs/g722.cpp
@@ -41,7 +41,7 @@ class G722 : public sfl::AudioCodec {
 
     public:
         G722() : sfl::AudioCodec(9, "G722", 16000, 320, 1), decode_state_(),
-        encode_state_() {
+            encode_state_() {
             bitrate_ = 64;
             hasDynamicPayload_ = false;
 
@@ -50,19 +50,18 @@ class G722 : public sfl::AudioCodec {
         }
 
     private:
-        int decode(SFLDataFormat *dst, unsigned char *src, size_t buf_size)
+        int decode(SFLAudioSample *dst, unsigned char *src, size_t buf_size)
         {
             return g722_decode(dst, src, buf_size);
         }
 
-        int encode(unsigned char *dst, SFLDataFormat *src, size_t /*buf_size*/)
+        int encode(unsigned char *dst, SFLAudioSample *src, size_t /*buf_size*/)
         {
             int out = g722_encode(dst, src, frameSize_);
             return out;
         }
 
-        static void g722_state_init(g722_state_t &state)
-        {
+        static void g722_state_init(g722_state_t &state) {
             state.itu_test_mode = false;
 
             // 8 => 64 kbps;  7 => 56 kbps;  6 => 48 kbps
@@ -86,12 +85,12 @@ class G722 : public sfl::AudioCodec {
             state.out_bits = 0;
         }
 
-        SFLDataFormat saturate(int32_t amp)
+        SFLAudioSample saturate(int32_t amp)
         {
-            SFLDataFormat amp16 = 0;
+            SFLAudioSample amp16 = 0;
 
             /* Hopefully this is optimised for the common case - not clipping */
-            amp16 = (SFLDataFormat) amp;
+            amp16 = (SFLAudioSample) amp;
 
             if (amp == amp16)
                 return amp16;
@@ -102,8 +101,7 @@ class G722 : public sfl::AudioCodec {
             return INT16_MIN;
         }
 
-        void block4_encode(int band, int d)
-        {
+        void block4_encode(int band, int d) {
             int wd1 = 0;
             int wd2 = 0;
             int wd3 = 0;
@@ -207,8 +205,7 @@ class G722 : public sfl::AudioCodec {
 
         }
 
-        void block4_decode(int band, int d)
-        {
+        void block4_decode(int band, int d) {
             int wd1 = 0;
             int wd2 = 0;
             int wd3 = 0;
@@ -313,7 +310,7 @@ class G722 : public sfl::AudioCodec {
             decode_state_.band[band].s = saturate(decode_state_.band[band].sp + decode_state_.band[band].sz);
         }
 
-        int g722_decode(SFLDataFormat amp[], const uint8_t g722_data[], int len)
+        int g722_decode(SFLAudioSample amp[], const uint8_t g722_data[], int len)
         {
             static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };
             static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3,  2, 1, 0 };
@@ -508,11 +505,11 @@ class G722 : public sfl::AudioCodec {
                 }
 
                 if (decode_state_.itu_test_mode) {
-                    amp[outlen++] = (SFLDataFormat)(rlow << 1);
-                    amp[outlen++] = (SFLDataFormat)(rhigh << 1);
+                    amp[outlen++] = (SFLAudioSample)(rlow << 1);
+                    amp[outlen++] = (SFLAudioSample)(rhigh << 1);
                 } else {
                     if (decode_state_.eight_k) {
-                        amp[outlen++] = (SFLDataFormat) rlow;
+                        amp[outlen++] = (SFLAudioSample) rlow;
                     } else {
                         /* Apply the receive QMF */
                         for (i = 0;  i < 22;  i++)
@@ -531,9 +528,9 @@ class G722 : public sfl::AudioCodec {
                             xout1 += decode_state_.x[2*i + 1]*qmf_coeffs[11 - i];
                         }
 
-                        amp[outlen++] = (SFLDataFormat)(xout1 >> 12);
+                        amp[outlen++] = (SFLAudioSample)(xout1 >> 12);
 
-                        amp[outlen++] = (SFLDataFormat)(xout2 >> 12);
+                        amp[outlen++] = (SFLAudioSample)(xout2 >> 12);
                     }
                 }
             }
@@ -541,7 +538,7 @@ class G722 : public sfl::AudioCodec {
             return outlen;
         }
 
-        int g722_encode(uint8_t g722_data[], const SFLDataFormat amp[], int len)
+        int g722_encode(uint8_t g722_data[], const SFLAudioSample amp[], int len)
         {
             static const int q6[32] = {
                 0,   35,   72,  110,  150,  190,  233,  276,
diff --git a/daemon/src/audio/codecs/g729.cpp b/daemon/src/audio/codecs/g729.cpp
index a263ceb1f38215d387e0cd0ca435b81f457ebc9c..217b21d6f964c5e1750154fbc41495297b57e03b 100644
--- a/daemon/src/audio/codecs/g729.cpp
+++ b/daemon/src/audio/codecs/g729.cpp
@@ -28,12 +28,13 @@
  *  as that of the covered work.
  */
 #include "g729.h"
+#include "sfl_types.h"
 #include <iostream>
 #include <dlfcn.h>
 #include <stdexcept>
 
-#define G729_TYPE_ENCODER        (void (*)(bcg729EncoderChannelContextStruct*, int16_t[], uint8_t[]))
-#define G729_TYPE_DECODER        (void (*)(bcg729DecoderChannelContextStruct*, uint8_t[], uint8_t, int16_t[]))
+#define G729_TYPE_ENCODER        (void (*)(bcg729EncoderChannelContextStruct*, SFLAudioSample[], uint8_t[]))
+#define G729_TYPE_DECODER        (void (*)(bcg729DecoderChannelContextStruct*, uint8_t[], uint8_t, SFLAudioSample[]))
 
 #define G729_TYPE_DECODER_INIT   (bcg729DecoderChannelContextStruct*(*)())
 #define G729_TYPE_ENCODER_INIT   (bcg729EncoderChannelContextStruct*(*)())
@@ -47,22 +48,23 @@ G729::G729() : sfl::AudioCodec(G729_PAYLOAD_TYPE, "G729", 8000, 160, 1),
     encoder_(0),
     decoder_(0)
 {
-   handler_ = dlopen("libbcg729.so.0", RTLD_NOW);
-   if (!handler_)
-       throw std::runtime_error("g729: did not open shared lib");
+    handler_ = dlopen("libbcg729.so.0", RTLD_NOW);
 
-   encoder_ = G729_TYPE_ENCODER dlsym(handler_, "bcg729Encoder");
-   loadError(dlerror());
-   decoder_ = G729_TYPE_DECODER dlsym(handler_, "bcg729Decoder");
-   loadError(dlerror());
+    if (!handler_)
+        throw std::runtime_error("g729: did not open shared lib");
 
-   bcg729DecoderChannelContextStruct*(*decInit)() = G729_TYPE_DECODER_INIT dlsym(handler_, "initBcg729DecoderChannel");
-   loadError(dlerror());
-   bcg729EncoderChannelContextStruct*(*encInit)() = G729_TYPE_ENCODER_INIT dlsym(handler_, "initBcg729EncoderChannel");
-   loadError(dlerror());
+    encoder_ = G729_TYPE_ENCODER dlsym(handler_, "bcg729Encoder");
+    loadError(dlerror());
+    decoder_ = G729_TYPE_DECODER dlsym(handler_, "bcg729Decoder");
+    loadError(dlerror());
 
-   decoderContext_ = (*decInit)();
-   encoderContext_ = (*encInit)();
+    bcg729DecoderChannelContextStruct*(*decInit)() = G729_TYPE_DECODER_INIT dlsym(handler_, "initBcg729DecoderChannel");
+    loadError(dlerror());
+    bcg729EncoderChannelContextStruct*(*encInit)() = G729_TYPE_ENCODER_INIT dlsym(handler_, "initBcg729EncoderChannel");
+    loadError(dlerror());
+
+    decoderContext_ = (*decInit)();
+    encoderContext_ = (*encInit)();
 }
 
 G729::~G729()
@@ -71,24 +73,24 @@ G729::~G729()
         dlclose(handler_);
 }
 
-int G729::decode(short *dst, unsigned char *buf, size_t buffer_size)
+int G729::decode(SFLAudioSample *dst, unsigned char *buf, size_t buffer_size)
 {
-   decoder_(decoderContext_, buf, false, dst);
-   decoder_(decoderContext_, buf + (buffer_size / 2), false, dst + 80);
-   return 160;
+    decoder_(decoderContext_, buf, false, dst);
+    decoder_(decoderContext_, buf + (buffer_size / 2), false, dst + 80);
+    return 160;
 }
 
-int G729::encode(unsigned char *dst, short *src, size_t buffer_size)
+int G729::encode(unsigned char *dst, SFLAudioSample *src, size_t buffer_size)
 {
-   encoder_(encoderContext_, src, dst);
-   encoder_(encoderContext_, src + (buffer_size / 2), dst + 10);
-   return 20;
+    encoder_(encoderContext_, src, dst);
+    encoder_(encoderContext_, src + (buffer_size / 2), dst + 10);
+    return 20;
 }
 
 void G729::loadError(const char *error)
 {
-   if (error != NULL)
-      throw std::runtime_error("G729 failed to load");
+    if (error != NULL)
+        throw std::runtime_error("G729 failed to load");
 }
 
 // cppcheck-suppress unusedFunction
diff --git a/daemon/src/audio/codecs/g729.h b/daemon/src/audio/codecs/g729.h
index 11d83c0d8fe0b03b727732031f6594372b3ff03e..1c2671b7473a7ba6cabdc1d830d84fc836d0f1b5 100644
--- a/daemon/src/audio/codecs/g729.h
+++ b/daemon/src/audio/codecs/g729.h
@@ -31,6 +31,7 @@
 #define G729_H_
 
 #include <cstdlib>
+#include "sfl_types.h"
 #include "noncopyable.h"
 
 #include "audiocodec.h"
@@ -43,8 +44,8 @@ public:
    G729();
    ~G729();
 private:
-   virtual int decode(short *dst, unsigned char *buf, size_t buffer_size);
-   virtual int encode(unsigned char *dst, short *src, size_t buffer_size);
+   virtual int decode(SFLAudioSample *dst, unsigned char *buf, size_t buffer_size);
+   virtual int encode(unsigned char *dst, SFLAudioSample *src, size_t buffer_size);
 
    NON_COPYABLE(G729);
    //Attributes
@@ -53,8 +54,8 @@ private:
    void* handler_;
 
    //Extern functions
-   void (*encoder_) (bcg729EncoderChannelContextStruct *encoderChannelContext, int16_t inputFrame[], uint8_t bitStream[]);
-   void (*decoder_) (bcg729DecoderChannelContextStruct *decoderChannelContext, uint8_t bitStream[], uint8_t frameErasureFlag, int16_t signal[]);
+   void (*encoder_) (bcg729EncoderChannelContextStruct *encoderChannelContext, SFLAudioSample inputFrame[], uint8_t bitStream[]);
+   void (*decoder_) (bcg729DecoderChannelContextStruct *decoderChannelContext, uint8_t bitStream[], uint8_t frameErasureFlag, SFLAudioSample signal[]);
 
    static void loadError(const char *error);
 };
diff --git a/daemon/src/audio/codecs/gsmcodec.cpp b/daemon/src/audio/codecs/gsmcodec.cpp
index b367b156a8f15deb3af1bd550ac7fe7d49a1f59b..9f5735d59ade18d91ab2b611388dafcfc1c1dbe8 100644
--- a/daemon/src/audio/codecs/gsmcodec.cpp
+++ b/daemon/src/audio/codecs/gsmcodec.cpp
@@ -46,10 +46,10 @@ extern "C" {
 
 class Gsm : public sfl::AudioCodec {
 
-public:
+    public:
         // _payload should be 3
         Gsm() : sfl::AudioCodec(3, "GSM", 8000, 160, 1),
-        decode_gsmhandle_(NULL), encode_gsmhandle_(NULL) {
+            decode_gsmhandle_(NULL), encode_gsmhandle_(NULL) {
             bitrate_ = 13.3;
             hasDynamicPayload_ = false;
 
@@ -60,13 +60,12 @@ public:
                 throw std::runtime_error("ERROR: encode_gsm_create\n");
         }
 
-        ~Gsm()
-        {
+        ~Gsm() {
             gsm_destroy(decode_gsmhandle_);
             gsm_destroy(encode_gsmhandle_);
         }
 private:
-        int decode(SFLDataFormat * dst, unsigned char * src, size_t /*buf_size*/)
+        int decode(SFLAudioSample * dst, unsigned char * src, size_t /*buf_size*/)
         {
             if (gsm_decode(decode_gsmhandle_, (gsm_byte*) src, (gsm_signal*) dst) < 0)
                 throw std::runtime_error("ERROR: gsm_decode\n");
@@ -74,7 +73,7 @@ private:
             return frameSize_;
         }
 
-        int encode(unsigned char * dst, SFLDataFormat * src, size_t /*buf_size*/)
+        int encode(unsigned char * dst, SFLAudioSample * src, size_t /*buf_size*/)
         {
             gsm_encode(encode_gsmhandle_, (gsm_signal*) src, (gsm_byte*) dst);
             return sizeof(gsm_frame);
diff --git a/daemon/src/audio/codecs/ilbc.cpp b/daemon/src/audio/codecs/ilbc.cpp
index c822558eedebcba89671109eb4a10888bf242bfc..1fb5a2835ca40ca35c4b3247bb03c817ad1eede5 100644
--- a/daemon/src/audio/codecs/ilbc.cpp
+++ b/daemon/src/audio/codecs/ilbc.cpp
@@ -29,6 +29,7 @@
  */
 
 #include "audiocodec.h"
+#include "sfl_types.h"
 #include <tr1/array>
 #include <algorithm>
 
@@ -41,8 +42,7 @@ class Ilbc: public sfl::AudioCodec {
         Ilbc() :
             sfl::AudioCodec(ILBC_PAYLOAD, "iLBC", 8000, ILBC_FRAME_SIZE, 1),
             ilbc_dec_(),
-            ilbc_enc_()
-        {
+            ilbc_enc_() {
             bitrate_ = 13.3;
 
             initDecode(&ilbc_dec_, 20, 1);
@@ -51,13 +51,13 @@ class Ilbc: public sfl::AudioCodec {
 
     private:
         // iLBC expects floating point data, so we have to convert
-        int decode(short *dst, unsigned char *src, size_t /*buf_size*/) {
+        int decode(SFLAudioSample *dst, unsigned char *src, size_t /*buf_size*/) {
             const int NORMAL_MODE = 1;
             iLBC_decode(dst, reinterpret_cast<WebRtc_UWord16*>(src), &ilbc_dec_, NORMAL_MODE);
             return frameSize_;
         }
 
-        int encode(unsigned char *dst, short* src, size_t /*buf_size*/) {
+        int encode(unsigned char *dst, SFLAudioSample * src, size_t /*buf_size*/) {
             iLBC_encode(reinterpret_cast<WebRtc_UWord16*>(dst), src, &ilbc_enc_);
             return frameSize_;
         }
diff --git a/daemon/src/audio/codecs/opus.cpp b/daemon/src/audio/codecs/opus.cpp
index 02b7df3f51e70e3a845e0a869c0199d0af47cbaa..a1583efb9205df18595df1606fdab6a35b108958 100644
--- a/daemon/src/audio/codecs/opus.cpp
+++ b/daemon/src/audio/codecs/opus.cpp
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
  *  Author:  Emmanuel Lepage <emmanuel.lepage@savoirfairelinux.com>
+ *  Author: Adrien Beraud <adrien.beraud@wisdomvibes.com>
  *
  *  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
@@ -28,45 +29,87 @@
  *  as that of the covered work.
  */
 #include "opus.h"
+#include "sfl_types.h"
 #include <stdexcept>
 #include <iostream>
 
-static const int Opus_PAYLOAD_TYPE = 104; // dynamic payload type, out of range of video (96-99)
 
-Opus::Opus() : sfl::AudioCodec(Opus_PAYLOAD_TYPE, "OPUS", CLOCK_RATE, FRAME_SIZE, CHANNELS),
+Opus::Opus() : sfl::AudioCodec(PAYLOAD_TYPE, "Opus", CLOCK_RATE, FRAME_SIZE, CHANNELS),
     encoder_(0),
-    decoder_(0)
+    decoder_(0),
+    interleaved_()
 {
-   hasDynamicPayload_ = true;
+    hasDynamicPayload_ = true;
 
-   int err = 0;
-   encoder_ = opus_encoder_create(CLOCK_RATE, CHANNELS, OPUS_APPLICATION_VOIP, &err);
-   if (err)
-       throw std::runtime_error("opus: could not create encoder");
+    int err = 0;
+    encoder_ = opus_encoder_create(CLOCK_RATE, CHANNELS, OPUS_APPLICATION_VOIP, &err);
 
-   decoder_ = opus_decoder_create(CLOCK_RATE, CHANNELS, &err);
-   if (err)
-       throw std::runtime_error("opus: could not create decoder");
+    if (err)
+        throw std::runtime_error("opus: could not create encoder");
+
+    decoder_ = opus_decoder_create(CLOCK_RATE, CHANNELS, &err);
+
+    if (err)
+        throw std::runtime_error("opus: could not create decoder");
 }
 
 Opus::~Opus()
 {
     if (encoder_)
         opus_encoder_destroy(encoder_);
+
     if (decoder_)
         opus_decoder_destroy(decoder_);
 }
 
-int Opus::decode(short *dst, unsigned char *buf, size_t buffer_size)
+int Opus::decode(SFLAudioSample *dst, unsigned char *buf, size_t buffer_size)
 {
-   return opus_decode(decoder_, buf, buffer_size, dst, FRAME_SIZE, 0);
+    return opus_decode(decoder_, buf, buffer_size, dst, FRAME_SIZE, 0);
 }
 
-int Opus::encode(unsigned char *dst, short *src, size_t buffer_size)
+int Opus::encode(unsigned char *dst, SFLAudioSample *src, size_t buffer_size)
 {
-   return opus_encode(encoder_, src, FRAME_SIZE, dst, buffer_size * 2);
+    return opus_encode(encoder_, src, FRAME_SIZE, dst, buffer_size * 2);
 }
 
+int Opus::decode(std::vector<std::vector<SFLAudioSample> > &dst, unsigned char *buf, size_t buffer_size)
+{
+    if (buf == NULL || dst.size() < 2) return 0;
+
+    interleaved_.resize(4 * FRAME_SIZE);
+    unsigned samples = opus_decode(decoder_, buf, buffer_size, interleaved_.data(), 2 * FRAME_SIZE, 0);
+
+    std::vector<SFLAudioSample>::iterator left_it = dst.at(0).begin();
+    std::vector<SFLAudioSample>::iterator right_it = dst.at(1).begin();
+    std::vector<opus_int16>::iterator it = interleaved_.begin();
+
+    // hard-coded 2-channels as it is the stereo version
+    for (unsigned i = 0; i < samples; i++) {
+        *left_it++ = *it++;
+        *right_it++ = *it++;
+    }
+
+    return samples;
+}
+
+int Opus::encode(unsigned char *dst, std::vector<std::vector<SFLAudioSample> > &src, size_t buffer_size)
+{
+    if (dst == NULL or src.size() < 2) return 0;
+
+    const unsigned samples = src.at(0).size();
+    interleaved_.resize(2 * samples);
+    std::vector<opus_int16>::iterator it = interleaved_.begin();
+
+    // hard-coded 2-channels as it is the stereo version
+    for (unsigned i = 0; i < samples; i++) {
+        *it++ = src.at(0)[i];
+        *it++ = src.at(1)[i];
+    }
+
+    return opus_encode(encoder_, interleaved_.data(), FRAME_SIZE, dst, buffer_size * 2);
+}
+
+
 // cppcheck-suppress unusedFunction
 extern "C" sfl::AudioCodec* AUDIO_CODEC_ENTRY()
 {
diff --git a/daemon/src/audio/codecs/opus.h b/daemon/src/audio/codecs/opus.h
index 160abc2fed491aad944405fee65eef3c8f6b8168..f1b5181c1d8fcc2667980ebd628169a49028d5a4 100644
--- a/daemon/src/audio/codecs/opus.h
+++ b/daemon/src/audio/codecs/opus.h
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
  *  Author:  Emmanuel Lepage <emmanuel.lepage@savoirfairelinux.com>
+ *  Author: Adrien Beraud <adrien.beraud@wisdomvibes.com>
  *
  *  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
@@ -31,6 +32,7 @@
 #define OPUS_H_
 
 #include "noncopyable.h"
+#include "sfl_types.h"
 
 #include "audiocodec.h"
 
@@ -40,17 +42,26 @@ class Opus : public sfl::AudioCodec {
 public:
    Opus();
    ~Opus();
+
+   static const uint8_t PAYLOAD_TYPE = 104; // dynamic payload type, out of range of video (96-99)
+
 private:
-   virtual int decode(short *dst, unsigned char *buf, size_t buffer_size);
-   virtual int encode(unsigned char *dst, short *src, size_t buffer_size);
+   virtual int decode(SFLAudioSample *dst, unsigned char *buf, size_t buffer_size);
+   virtual int encode(unsigned char *dst, SFLAudioSample *src, size_t buffer_size);
+
+   //multichannel version
+   virtual int decode(std::vector<std::vector<SFLAudioSample> > &dst, unsigned char *buf, size_t buffer_size);
+   virtual int encode(unsigned char *dst, std::vector<std::vector<SFLAudioSample> > &src, size_t buffer_size);
 
    NON_COPYABLE(Opus);
    //Attributes
    OpusEncoder *encoder_;
    OpusDecoder *decoder_;
+   std::vector<opus_int16> interleaved_;
+
    static const int FRAME_SIZE = 160;
    static const int CLOCK_RATE = 16000;
-   static const int CHANNELS   = 1;
+   static const int CHANNELS   = 2;
 };
 
 #endif
diff --git a/daemon/src/audio/codecs/speexcodec.h b/daemon/src/audio/codecs/speexcodec.h
index 20b1b66a04ab969a3eadfb23def98f1d1d7c99f4..adb38bde309fb2418fa6a3a21f8cf8531355a33d 100644
--- a/daemon/src/audio/codecs/speexcodec.h
+++ b/daemon/src/audio/codecs/speexcodec.h
@@ -30,6 +30,7 @@
  */
 
 #include "global.h"
+#include "sfl_types.h"
 #include "audiocodec.h"
 #include "noncopyable.h"
 #include "array_size.h"
@@ -83,13 +84,13 @@ private:
 
         NON_COPYABLE(Speex);
 
-        virtual int decode(short *dst, unsigned char *src, size_t buf_size) {
+        virtual int decode(SFLAudioSample *dst, unsigned char *src, size_t buf_size) {
             speex_bits_read_from(&speex_dec_bits_, (char*) src, buf_size);
             speex_decode_int(speex_dec_state_, &speex_dec_bits_, dst);
             return frameSize_;
         }
 
-        virtual int encode(unsigned char *dst, short *src, size_t buf_size) {
+        virtual int encode(unsigned char *dst, SFLAudioSample *src, size_t buf_size) {
             speex_bits_reset(&speex_enc_bits_);
             speex_encode_int(speex_enc_state_, src, &speex_enc_bits_);
             return speex_bits_write(&speex_enc_bits_, (char*) dst, buf_size);
diff --git a/daemon/src/audio/codecs/ulaw.cpp b/daemon/src/audio/codecs/ulaw.cpp
index 7a2a96b6c966288bf44123d07ab072cacdd4aba5..b0a152c11377f7bdeaefaeb21e15cc8c494b2599 100644
--- a/daemon/src/audio/codecs/ulaw.cpp
+++ b/daemon/src/audio/codecs/ulaw.cpp
@@ -41,28 +41,27 @@ class Ulaw : public sfl::AudioCodec {
         }
 
     private:
-        int decode(SFLDataFormat *dst, unsigned char *src, size_t buf_size) {
+        int decode(SFLAudioSample *dst, unsigned char *src, size_t buf_size) {
             for (unsigned char* end = src + buf_size; src < end; ++src, ++dst)
                 *dst = ULawDecode(*src);
 
             return buf_size;
         }
 
-        int encode(unsigned char *dst, SFLDataFormat *src, size_t buf_size) {
+        int encode(unsigned char *dst, SFLAudioSample *src, size_t buf_size) {
             for (unsigned char * end = dst + buf_size; dst < end; ++src, ++dst)
                 *dst = ULawEncode(*src);
 
             return buf_size;
         }
 
-        SFLDataFormat ULawDecode(uint8 ulaw)
-        {
+        SFLAudioSample ULawDecode(uint8_t ulaw) {
             ulaw ^= 0xff;  // u-law has all bits inverted for transmission
             int linear = ulaw & 0x0f;
             linear <<= 3;
             linear |= 0x84;  // Set MSB (0x80) and a 'half' bit (0x04) to place PCM value in middle of range
 
-            uint shift = ulaw >> 4;
+            uint8_t shift = ulaw >> 4;
             shift &= 7;
             linear <<= shift;
             linear -= 0x84; // Subract uLaw bias
@@ -73,10 +72,9 @@ class Ulaw : public sfl::AudioCodec {
                 return linear;
         }
 
-        uint8 ULawEncode(SFLDataFormat pcm16)
-        {
+        uint8_t ULawEncode(SFLAudioSample pcm16) {
             int p = pcm16;
-            uint u;  // u-law value we are forming
+            uint8_t u;  // u-law value we are forming
 
             if (p < 0) {
                 p = ~p;
diff --git a/daemon/src/audio/dcblocker.cpp b/daemon/src/audio/dcblocker.cpp
index 0acbb63bc6ca17903ab3f6a8e39d03706496f8da..92e631ba532394a370146c098f6cc170a78708ef 100644
--- a/daemon/src/audio/dcblocker.cpp
+++ b/daemon/src/audio/dcblocker.cpp
@@ -30,27 +30,46 @@
 
 #include "dcblocker.h"
 
-DcBlocker::DcBlocker() : y_(0), x_(0), xm1_(0), ym1_(0)
+DcBlocker::DcBlocker(unsigned channels /* = 1 */)
+    : states(channels, (struct StreamState){0, 0, 0, 0})
 {}
 
 void DcBlocker::reset()
 {
-    y_ = 0;
-    x_ = 0;
-    xm1_ = 0;
-    ym1_ = 0;
+    states.assign(states.size(), (struct StreamState){0, 0, 0, 0});
 }
 
-void DcBlocker::process(SFLDataFormat *out, SFLDataFormat *in, int samples)
+void DcBlocker::doProcess(SFLAudioSample *out, SFLAudioSample *in, unsigned samples, struct StreamState * state)
 {
-    for (int i = 0; i < samples; ++i) {
-        x_ = in[i];
+    for (unsigned i = 0; i < samples; ++i) {
+        state->x_ = in[i];
 
-        y_ = (SFLDataFormat) ((float) x_ - (float) xm1_ + 0.9999 * (float) y_);
-        xm1_ = x_;
-        ym1_ = y_;
 
-        out[i] = y_;
+        state->y_ = (SFLAudioSample) ((float) state->x_ - (float) state->xm1_ + 0.9999 * (float) state->y_);
+        state->xm1_ = state->x_;
+        state->ym1_ = state->y_;
+
+        out[i] = state->y_;
+    }
+}
+
+void DcBlocker::process(SFLAudioSample *out, SFLAudioSample *in, int samples)
+{
+    if(out == NULL or in == NULL or samples == 0) return;
+    doProcess(out, in, samples, &states[0]);
+}
+
+void DcBlocker::process(AudioBuffer& buf)
+{
+    const size_t chans = buf.channels();
+    const size_t samples = buf.samples();
+    if(chans > states.size())
+        states.resize(buf.channels(), (struct StreamState){0, 0, 0, 0});
+
+    unsigned i;
+    for(i=0; i<chans; i++) {
+        SFLAudioSample *chan = buf.getChannel(i)->data();
+        doProcess(chan, chan, samples, &states[i]);
     }
 }
 
diff --git a/daemon/src/audio/dcblocker.h b/daemon/src/audio/dcblocker.h
index fd5674e82271f2db2d66dc1df06147292145eea9..878b6855a23d92784c412c4172419169177a9102 100644
--- a/daemon/src/audio/dcblocker.h
+++ b/daemon/src/audio/dcblocker.h
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
  *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *  Author: Adrien Beraud <adrien.beraud@gmail.com>
  *
  *  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
@@ -32,16 +33,28 @@
 #define DCBLOCKER_H
 
 #include "sfl_types.h"
+#include "audiobuffer.h"
 
 class DcBlocker {
     public:
-        DcBlocker();
+        DcBlocker(unsigned channels = 1);
         void reset();
-        void process(SFLDataFormat *out, SFLDataFormat *in, int samples);
+
+        void process(SFLAudioSample *out, SFLAudioSample *in, int samples);
+
+        /**
+         * In-place processing of all samples in buf (each channel treated independently)
+         */
+        void process(AudioBuffer& buf);
 
     private:
+        struct StreamState {
+            SFLAudioSample y_, x_, xm1_, ym1_;
+        };
+
+        void doProcess(SFLAudioSample *out, SFLAudioSample *in, unsigned samples, struct StreamState * state);
 
-        SFLDataFormat y_, x_, xm1_, ym1_;
+        std::vector<StreamState> states;
 };
 
 #endif
diff --git a/daemon/src/audio/delaydetection.cpp b/daemon/src/audio/delaydetection.cpp
index 46bbdce131f7d623d90973c0ac84a21a8c3b312a..7dd8c56fc9330582d914cd9d434cd30a102f85ff 100644
--- a/daemon/src/audio/delaydetection.cpp
+++ b/daemon/src/audio/delaydetection.cpp
@@ -38,26 +38,26 @@
 namespace {
 // decimation filter coefficient
 const float decimationCoefs[] = {-0.09870257, 0.07473655, 0.05616626, 0.04448337, 0.03630817, 0.02944626,
-                           0.02244098, 0.01463477, 0.00610982, -0.00266367, -0.01120109, -0.01873722,
-                           -0.02373243, -0.02602213, -0.02437806, -0.01869834, -0.00875287, 0.00500204,
-                           0.02183252, 0.04065763, 0.06015944, 0.0788299, 0.09518543, 0.10799179,
-                           0.1160644,  0.12889288, 0.1160644, 0.10799179, 0.09518543, 0.0788299,
-                           0.06015944, 0.04065763, 0.02183252, 0.00500204, -0.00875287, -0.01869834,
-                           -0.02437806, -0.02602213, -0.02373243, -0.01873722, -0.01120109, -0.00266367,
-                           0.00610982, 0.01463477, 0.02244098, 0.02944626, 0.03630817, 0.04448337,
-                           0.05616626,  0.07473655, -0.09870257
-                          };
+                                 0.02244098, 0.01463477, 0.00610982, -0.00266367, -0.01120109, -0.01873722,
+                                 -0.02373243, -0.02602213, -0.02437806, -0.01869834, -0.00875287, 0.00500204,
+                                 0.02183252, 0.04065763, 0.06015944, 0.0788299, 0.09518543, 0.10799179,
+                                 0.1160644,  0.12889288, 0.1160644, 0.10799179, 0.09518543, 0.0788299,
+                                 0.06015944, 0.04065763, 0.02183252, 0.00500204, -0.00875287, -0.01869834,
+                                 -0.02437806, -0.02602213, -0.02373243, -0.01873722, -0.01120109, -0.00266367,
+                                 0.00610982, 0.01463477, 0.02244098, 0.02944626, 0.03630817, 0.04448337,
+                                 0.05616626,  0.07473655, -0.09870257
+                                };
 std::vector<double> ird(decimationCoefs, decimationCoefs + sizeof(decimationCoefs) /sizeof(float));
 
 
 // decimation filter coefficient
 const float bandpassCoefs[] = {0.06278034, -0.0758545, -0.02274943, -0.0084497, 0.0702427, 0.05986113,
-                         0.06436469, -0.02412049, -0.03433526, -0.07568665, -0.03214543, -0.07236507,
-                         -0.06979052, -0.12446371, -0.05530828, 0.00947243, 0.15294699, 0.17735563,
-                         0.15294699, 0.00947243, -0.05530828, -0.12446371, -0.06979052, -0.07236507,
-                         -0.03214543, -0.07568665, -0.03433526, -0.02412049,  0.06436469, 0.05986113,
-                         0.0702427, -0.0084497, -0.02274943, -0.0758545, 0.06278034
-                        };
+                               0.06436469, -0.02412049, -0.03433526, -0.07568665, -0.03214543, -0.07236507,
+                               -0.06979052, -0.12446371, -0.05530828, 0.00947243, 0.15294699, 0.17735563,
+                               0.15294699, 0.00947243, -0.05530828, -0.12446371, -0.06979052, -0.07236507,
+                               -0.03214543, -0.07568665, -0.03433526, -0.02412049,  0.06436469, 0.05986113,
+                               0.0702427, -0.0084497, -0.02274943, -0.0758545, 0.06278034
+                              };
 std::vector<double> irb(bandpassCoefs, bandpassCoefs + sizeof(bandpassCoefs) / sizeof(float));
 } // end anonymous namespace
 
@@ -116,7 +116,7 @@ DelayDetection::DelayDetection() :
 
 }
 
-void DelayDetection::putData(SFLDataFormat *inputData, int nbSamples)
+void DelayDetection::putData(SFLAudioSample *inputData, int nbSamples)
 {
     // Machine may already got a spkr and is waiting for mic or computing correlation
     if (nbSpkrSampleStored_ == WINDOW_SIZE)
@@ -144,7 +144,7 @@ void DelayDetection::putData(SFLDataFormat *inputData, int nbSamples)
     internalState_ = WaitForMic;
 }
 
-void DelayDetection::process(SFLDataFormat *inputData, int nbSamples)
+void DelayDetection::process(SFLAudioSample *inputData, int nbSamples)
 {
 
     if (internalState_ != WaitForMic)
@@ -233,7 +233,7 @@ double DelayDetection::correlate(float *sig1, float *sig2, short size)
 }
 
 
-void DelayDetection::convertInt16ToFloat32(SFLDataFormat *input, float *output, int nbSamples)
+void DelayDetection::convertInt16ToFloat32(SFLAudioSample *input, float *output, int nbSamples)
 {
     static const float S2F_FACTOR = .000030517578125f;
     int len = nbSamples;
diff --git a/daemon/src/audio/delaydetection.h b/daemon/src/audio/delaydetection.h
index 47f4a5c9961226c91e4942ccb6a195b22fa325b4..d82fd97f68d74efadf703bf3f8472ce89ea8dd15 100644
--- a/daemon/src/audio/delaydetection.h
+++ b/daemon/src/audio/delaydetection.h
@@ -84,9 +84,9 @@ class DelayDetection {
 
         ~DelayDetection();
 
-        void putData(SFLDataFormat *inputData, int samples);
+        void putData(SFLAudioSample *inputData, int samples);
 
-        void process(SFLDataFormat *inputData, int samples);
+        void process(SFLAudioSample *inputData, int samples);
 
     private:
 
@@ -107,7 +107,7 @@ class DelayDetection {
          */
         double correlate(float *sig1, float *sig2, short size);
 
-        void convertInt16ToFloat32(SFLDataFormat *input, float *ouput, int nbSamples);
+        void convertInt16ToFloat32(SFLAudioSample *input, float *ouput, int nbSamples);
 
         void downsampleData(float *input, float *output, int nbSamples, int factor);
 
diff --git a/daemon/src/audio/gaincontrol.cpp b/daemon/src/audio/gaincontrol.cpp
index 7ae0c03461a15107aa076e2eeba956ca682c70d4..8e8bc07b2954049b3b269a766d762e8821282abe 100644
--- a/daemon/src/audio/gaincontrol.cpp
+++ b/daemon/src/audio/gaincontrol.cpp
@@ -56,7 +56,12 @@ GainControl::GainControl(double sr, double target) : averager_(sr, SFL_GAIN_ATTA
     DEBUG("Target gain %f dB (%f linear)", targetLeveldB_, targetLevelLinear_);
 }
 
-void GainControl::process(SFLDataFormat *buf, int samples)
+void GainControl::process(AudioBuffer& buf)
+{
+    process(buf.getChannel(0)->data(), buf.samples());
+}
+
+void GainControl::process(SFLAudioSample *buf, int samples)
 {
     double rms, rmsAvgLevel, in, out, diffRms, maxRms;
 
@@ -64,7 +69,7 @@ void GainControl::process(SFLDataFormat *buf, int samples)
 
     for (int i = 0; i < samples; i++) {
         // linear conversion
-        in = (double)buf[i] / (double)SHRT_MAX;
+        in = (double) buf[i] / (double) SFL_DATA_FORMAT_MAX;
 
         out = currentGain_ * in;
 
@@ -76,7 +81,7 @@ void GainControl::process(SFLDataFormat *buf, int samples)
 
         out = limiter_.limit(out);
 
-        buf[i] = (short)(out * (double)SHRT_MAX);
+        buf[i] = (SFLAudioSample) (out * (double) SFL_DATA_FORMAT_MAX);
     }
 
     diffRms = maxRms - targetLevelLinear_;
@@ -106,6 +111,7 @@ double GainControl::DetectionAverage::getAverage(double in)
         previous_y_ = ((1.0 - g_a_) * in) + (g_a_ * previous_y_);
     else
         previous_y_ = ((1.0 - g_r_) * in) + (g_r_ * previous_y_);
+
     return previous_y_;
 }
 
@@ -115,7 +121,7 @@ GainControl::Limiter::Limiter(double r, double thresh) : ratio_(r), threshold_(t
 double GainControl::Limiter::limit(double in) const
 {
     double out = (in > threshold_ ? (ratio_ * (in - threshold_)) + threshold_ :
-           in < -threshold_ ? (ratio_ * (in + threshold_)) - threshold_ : in);
+                  in < -threshold_ ? (ratio_ * (in + threshold_)) - threshold_ : in);
 
     return out;
 }
diff --git a/daemon/src/audio/gaincontrol.h b/daemon/src/audio/gaincontrol.h
index 4c36953a76c742f5cc7fdd52a01fc5160fbbdc62..2187c17f195231d7be27ce98ed15f7cd956e64f4 100644
--- a/daemon/src/audio/gaincontrol.h
+++ b/daemon/src/audio/gaincontrol.h
@@ -32,6 +32,7 @@
 #define GAINCONTROL_H
 
 #include "global.h"
+#include "audiobuffer.h"
 
 class GainControl {
 
@@ -48,7 +49,8 @@ class GainControl {
          * /param Input audio buffer
          * /param Input samples
          */
-        void process(SFLDataFormat *, int samples);
+        void process(SFLAudioSample *, int samples);
+        void process(AudioBuffer& buf);
 
     private:
         class DetectionAverage {
diff --git a/daemon/src/audio/mainbuffer.cpp b/daemon/src/audio/mainbuffer.cpp
index f98abd11de85717466123f363aa1b2bd6850b091..61d3f73ff8fe1c39da5711154ae5356545aeb1ef 100644
--- a/daemon/src/audio/mainbuffer.cpp
+++ b/daemon/src/audio/mainbuffer.cpp
@@ -47,8 +47,9 @@ MainBuffer::MainBuffer() : ringBufferMap_(), callIDMap_(), mutex_(), internalSam
 MainBuffer::~MainBuffer()
 {
     // delete any ring buffers that didn't get removed
-    for (RingBufferMap::iterator iter = ringBufferMap_.begin(); iter != ringBufferMap_.end(); ++iter)
-        delete iter->second;
+    for (auto &item : ringBufferMap_)
+        delete item.second;
+
     pthread_mutex_destroy(&mutex_);
 }
 
@@ -88,6 +89,7 @@ void MainBuffer::removeCallIDSet(const std::string &set_id)
 void MainBuffer::addCallIDtoSet(const std::string &set_id, const std::string &call_id)
 {
     CallIDSet* callid_set = getCallIDSet(set_id);
+
     if (callid_set)
         callid_set->insert(call_id);
     else
@@ -228,24 +230,23 @@ void MainBuffer::unBindAll(const std::string & call_id)
 
     CallIDSet temp_set(*callid_set);
 
-    for (CallIDSet::iterator iter_set = temp_set.begin();
-         iter_set != temp_set.end(); ++iter_set) {
-        std::string call_id_in_set(*iter_set);
-        unBindCallID(call_id, call_id_in_set);
-    }
+    for (const auto &item_set : temp_set)
+        unBindCallID(call_id, item_set);
 }
 
-void MainBuffer::putData(void *buffer, size_t toCopy, const std::string &call_id)
+//void MainBuffer::putData(void *buffer, size_t toCopy, const std::string &call_id)
+void MainBuffer::putData(AudioBuffer& buffer, const std::string &call_id)
 {
     sfl::ScopedLock guard(mutex_);
 
     RingBuffer* ring_buffer = getRingBuffer(call_id);
 
     if (ring_buffer)
-        ring_buffer->put(buffer, toCopy);
+        ring_buffer->put(buffer);
 }
 
-size_t MainBuffer::getData(void *buffer, size_t toCopy, const std::string &call_id)
+//size_t MainBuffer::getData(void *buffer, size_t toCopy, const std::string &call_id)
+size_t MainBuffer::getData(AudioBuffer& buffer, const std::string &call_id)
 {
     sfl::ScopedLock guard(mutex_);
 
@@ -259,25 +260,21 @@ size_t MainBuffer::getData(void *buffer, size_t toCopy, const std::string &call_
         CallIDSet::iterator iter_id = callid_set->begin();
 
         if (iter_id != callid_set->end())
-            return getDataByID(buffer, toCopy, *iter_id, call_id);
+            return getDataByID(buffer, *iter_id, call_id); //return getDataByID(buffer, toCopy, *iter_id, call_id);
         else
             return 0;
     } else {
-        memset(buffer, 0, toCopy);
+        buffer.reset();
+        buffer.setSampleRate(internalSamplingRate_);
 
         size_t size = 0;
+        AudioBuffer mixBuffer(buffer);
 
-        for (CallIDSet::iterator iter_id = callid_set->begin();
-             iter_id != callid_set->end(); ++iter_id) {
-            size_t nbSmplToCopy = toCopy / sizeof(SFLDataFormat);
-            SFLDataFormat mixBuffer[nbSmplToCopy];
-            memset(mixBuffer, 0, toCopy);
-            size = getDataByID(mixBuffer, toCopy, *iter_id, call_id);
+        for (const auto &item_id : *callid_set) {
+            size = getDataByID(mixBuffer, item_id, call_id);
 
             if (size > 0) {
-                SFLDataFormat *dest = static_cast<SFLDataFormat*>(buffer);
-                for (size_t k = 0; k < nbSmplToCopy; ++k)
-                    dest[k] += mixBuffer[k];
+                buffer.mix(mixBuffer);
             }
         }
 
@@ -285,12 +282,18 @@ size_t MainBuffer::getData(void *buffer, size_t toCopy, const std::string &call_
     }
 }
 
-size_t MainBuffer::getDataByID(void *buffer, size_t toCopy, const std::string & call_id, const std::string & reader_id)
+size_t MainBuffer::getDataByID(AudioBuffer& buffer, const std::string & call_id, const std::string & reader_id)
 {
     RingBuffer* ring_buffer = getRingBuffer(call_id);
-    return ring_buffer ? ring_buffer->get(buffer, toCopy, reader_id) : 0;
+    return ring_buffer ? ring_buffer->get(buffer, reader_id) : 0;
 }
 
+/*size_t MainBuffer::getDataByID(void *buffer, size_t toCopy, const std::string & call_id, const std::string & reader_id)
+{
+    RingBuffer* ring_buffer = getRingBuffer(call_id);
+    return ring_buffer ? ring_buffer->get(buffer, toCopy, reader_id) : 0;
+}*/
+
 size_t MainBuffer::availableForGet(const std::string &call_id)
 {
     sfl::ScopedLock guard(mutex_);
@@ -310,20 +313,21 @@ size_t MainBuffer::availableForGet(const std::string &call_id)
 
     } else {
 
-        size_t availableBytes = INT_MAX;
-        for (CallIDSet::iterator i = callid_set->begin(); i != callid_set->end(); ++i) {
-            const size_t nbBytes = availableForGetByID(*i, call_id);
+        size_t availableSamples = INT_MAX;
+
+        for (auto &i : *callid_set) {
+            const size_t nbSamples = availableForGetByID(i, call_id);
 
-            if (nbBytes != 0)
-                availableBytes = std::min(availableBytes, nbBytes);
+            if (nbSamples != 0)
+                availableSamples = std::min(availableSamples, nbSamples);
         }
 
-        return availableBytes != INT_MAX ? availableBytes : 0;
+        return availableSamples != INT_MAX ? availableSamples : 0;
     }
 }
 
 size_t MainBuffer::availableForGetByID(const std::string &call_id,
-                                const std::string &reader_id) const
+                                       const std::string &reader_id) const
 {
     if (call_id != DEFAULT_ID and reader_id == call_id)
         ERROR("RingBuffer has a readpointer on itself");
@@ -347,8 +351,8 @@ size_t MainBuffer::discard(size_t toDiscard, const std::string &call_id)
     if (!callid_set or callid_set->empty())
         return 0;
 
-    for (CallIDSet::iterator iter = callid_set->begin(); iter != callid_set->end(); ++iter)
-        discardByID(toDiscard, *iter, call_id);
+    for (auto &item : *callid_set)
+        discardByID(toDiscard, item, call_id);
 
     return toDiscard;
 }
@@ -370,9 +374,8 @@ void MainBuffer::flush(const std::string & call_id)
     if (callid_set == NULL)
         return;
 
-    for (CallIDSet::iterator iter = callid_set->begin(); iter != callid_set->end(); ++iter)
-        flushByID(*iter, call_id);
-
+    for (auto &item : *callid_set)
+        flushByID(item, call_id);
 }
 
 void MainBuffer::flushByID(const std::string & call_id, const std::string & reader_id)
@@ -386,23 +389,24 @@ void MainBuffer::flushByID(const std::string & call_id, const std::string & read
 
 void MainBuffer::flushAllBuffers()
 {
-    for (RingBufferMap::iterator iter = ringBufferMap_.begin(); iter != ringBufferMap_.end(); ++iter)
-        iter->second->flushAll();
+    for (auto &item : ringBufferMap_)
+        item.second->flushAll();
 }
 
 void MainBuffer::dumpInfo()
 {
     sfl::ScopedLock guard(mutex_);
+
     // print each call and bound call ids
-    for (CallIDMap::const_iterator iter_call = callIDMap_.begin(); iter_call != callIDMap_.end(); ++iter_call) {
+    for (const auto &item_call : callIDMap_) {
         std::string dbg_str("    Call: \t");
-        dbg_str.append(iter_call->first);
+        dbg_str.append(item_call.first);
         dbg_str.append("   is bound to: \t");
 
-        CallIDSet *call_id_set = iter_call->second;
+        CallIDSet *call_id_set = item_call.second;
 
-        for (CallIDSet::iterator iter = call_id_set->begin(); iter != call_id_set->end(); ++iter) {
-            dbg_str.append(*iter);
+        for (const auto &item : *call_id_set) {
+            dbg_str.append(item);
             dbg_str.append(", ");
         }
 
@@ -410,23 +414,25 @@ void MainBuffer::dumpInfo()
     }
 
     // Print ringbuffers ids and readpointers
-    for (RingBufferMap::const_iterator iter_buffer = ringBufferMap_.begin(); iter_buffer != ringBufferMap_.end(); ++iter_buffer) {
+    for (const auto &item_buffer : ringBufferMap_) {
         std::string dbg_str("    Buffer: \t");
 
-        dbg_str.append(iter_buffer->first);
+        dbg_str.append(item_buffer.first);
         dbg_str.append("   as read pointer: \t");
 
-        RingBuffer* rbuffer = iter_buffer->second;
+        RingBuffer* rbuffer = item_buffer.second;
+
         if (rbuffer) {
             ReadPointer* rpointer = rbuffer->getReadPointerList();
 
             if (rpointer) {
-                for (ReadPointer::iterator iter = rpointer->begin(); iter != rpointer->end(); ++iter) {
-                    dbg_str.append(iter->first);
+                for (const auto &item : *rpointer) {
+                    dbg_str.append(item.first);
                     dbg_str.append(", ");
                 }
             }
         }
+
         DEBUG("%s", dbg_str.c_str());
     }
 }
diff --git a/daemon/src/audio/mainbuffer.h b/daemon/src/audio/mainbuffer.h
index 17e137b7314e345412337cc57ec47cb82ed3f97e..da03075e1d5870ff5ef26abcbded15fda9a69762 100644
--- a/daemon/src/audio/mainbuffer.h
+++ b/daemon/src/audio/mainbuffer.h
@@ -36,6 +36,8 @@
 #include <string>
 #include <pthread.h>
 
+#include "audiobuffer.h"
+
 class RingBuffer;
 
 typedef std::set<std::string> CallIDSet;
@@ -80,9 +82,11 @@ class MainBuffer {
 
         void unBindAll(const std::string &call_id);
 
-        void putData(void *buffer, size_t toCopy, const std::string &call_id);
+        //void putData(void *buffer, size_t toCopy, const std::string &call_id);
+        void putData(AudioBuffer& buffer, const std::string &call_id);
 
-        size_t getData(void *buffer, size_t toCopy, const std::string &call_id);
+        //size_t getData(void *buffer, size_t toCopy, const std::string &call_id);
+        size_t getData(AudioBuffer& buffer, const std::string &call_id);
 
         size_t availableForGet(const std::string &call_id);
 
@@ -119,7 +123,8 @@ class MainBuffer {
         RingBuffer* getRingBuffer(const std::string &call_id);
         const RingBuffer* getRingBuffer(const std::string & call_id) const;
 
-        size_t getDataByID(void *buffer, size_t toCopy, const std::string &call_id, const std::string &reader_id);
+        //size_t getDataByID(void *buffer, size_t toCopy, const std::string &call_id, const std::string &reader_id);
+        size_t getDataByID(AudioBuffer& buffer, const std::string &call_id, const std::string &reader_id);
 
         size_t availableForGetByID(const std::string &call_id, const std::string &reader_id) const;
 
diff --git a/daemon/src/audio/noisesuppress.cpp b/daemon/src/audio/noisesuppress.cpp
index 96092f5fa31fe02fb0c0b1d5e246201c948f3881..961cb88215d841775f51cb44be8d02bb24471afd 100644
--- a/daemon/src/audio/noisesuppress.cpp
+++ b/daemon/src/audio/noisesuppress.cpp
@@ -62,8 +62,9 @@ NoiseSuppress::~NoiseSuppress()
     noiseState_ = 0;
 }
 
-void NoiseSuppress::process(SFLDataFormat *data, int samples)
+void NoiseSuppress::process(AudioBuffer& buff, int samples)
 {
+    SFLAudioSample* data = buff.getChannel(0)->data();
     if (noiseState_) {
         assert(smplPerFrame_ == samples);
         speex_preprocess_run(noiseState_, data);
diff --git a/daemon/src/audio/noisesuppress.h b/daemon/src/audio/noisesuppress.h
index 86a4f7822e09b72a85bda03a806cf5c5be82d0bf..afc56a20eb578caeb82ea05e4b13d99b61ee79a4 100644
--- a/daemon/src/audio/noisesuppress.h
+++ b/daemon/src/audio/noisesuppress.h
@@ -32,14 +32,15 @@
 #define NOISESUPPRESS_H
 
 #include <speex/speex_preprocess.h>
-#include "sfl_types.h"
 #include "noncopyable.h"
+#include "audiobuffer.h"
 
 class NoiseSuppress {
     public:
         NoiseSuppress(int smplPerFrame, int samplingRate);
         ~NoiseSuppress();
-        void process(SFLDataFormat *data, int samples);
+        //void process(SFLAudioSample *data, int samples);
+        void process(AudioBuffer& buf, int samples);
 
     private:
         NON_COPYABLE(NoiseSuppress);
diff --git a/daemon/src/audio/opensl/opensllayer.cpp b/daemon/src/audio/opensl/opensllayer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..76212e7e21a7ebe41cffbaebff4feb46a8fbc414
--- /dev/null
+++ b/daemon/src/audio/opensl/opensllayer.cpp
@@ -0,0 +1,770 @@
+/*
+ *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
+ *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *
+ *  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, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#include <cstdio>
+#include <cassert>
+
+#include "logger.h"
+#include "array_size.h"
+#include "manager.h"
+#include "mainbuffer.h"
+
+#include "opensllayer.h"
+
+const int OpenSLLayer::NB_BUFFER_PLAYBACK_QUEUE = ANDROID_BUFFER_QUEUE_LENGTH;
+const int OpenSLLayer::NB_BUFFER_CAPTURE_QUEUE = ANDROID_BUFFER_QUEUE_LENGTH;
+
+static long sawPtr = 0;
+static void generateSawTooth(short *buffer, int length)
+{
+    assert(NULL != buffer);
+    assert(length > 0);
+
+    unsigned int i;
+
+    for (i = 0; i < length; ++i, ++sawPtr) {
+        buffer[i] = 32768 - ((sawPtr % 10) * 6600);
+    }
+}
+
+class OpenSLThread {
+    public:
+        OpenSLThread(OpenSLLayer *opensl);
+        ~OpenSLThread();
+        void initAudioLayer();
+        void start();
+        bool isRunning() const;
+
+    private:
+        void run();
+        static void *runCallback(void *context);
+
+        NON_COPYABLE(OpenSLThread);
+        pthread_t thread_;
+        OpenSLLayer* opensl_;
+        bool running_;
+};
+
+OpenSLThread::OpenSLThread(OpenSLLayer *opensl)
+    : thread_(0), opensl_(opensl), running_(false)
+{}
+
+OpenSLThread::~OpenSLThread()
+{
+    running_ = false;
+    opensl_->shutdownAudioEngine();
+
+    if (thread_)
+        pthread_join(thread_, NULL);
+}
+
+void
+OpenSLThread::start()
+{
+    running_ = true;
+    pthread_create(&thread_, NULL, &runCallback, this);
+}
+
+void *
+OpenSLThread::runCallback(void *data)
+{
+    OpenSLThread *context = static_cast<OpenSLThread*>(data);
+    context->run();
+    return NULL;
+}
+
+bool
+OpenSLThread::isRunning() const
+{
+    return running_;
+}
+
+void
+OpenSLThread::initAudioLayer()
+{
+    opensl_->initAudioEngine();
+    opensl_->initAudioPlayback();
+    opensl_->initAudioCapture();
+}
+
+/**
+ * Reimplementation of run()
+ */
+void
+OpenSLThread::run()
+{
+    initAudioLayer();
+
+    opensl_->startAudioPlayback();
+    opensl_->startAudioCapture();
+
+    while (opensl_->isStarted_)
+        usleep(20000); // 20 ms
+}
+
+// Constructor
+OpenSLLayer::OpenSLLayer()
+    : indexIn_(0)
+    , indexOut_(0)
+    , indexRing_(0)
+    , audioThread_(0)
+    , isStarted_(false)
+    , engineObject_(0)
+    , engineInterface_(0)
+    , outputMixer_(0)
+    , playerObject_(0)
+    , recorderObject_(0)
+    , playerInterface_(0)
+    , recorderInterface_(0)
+    , playbackBufferQueue_(0)
+    , recorderBufferQueue_(0)
+    , playbackBufferIndex_(0)
+    , recordBufferIndex_(0)
+    , playbackBufferStack_(ANDROID_BUFFER_QUEUE_LENGTH)
+    , recordBufferStack_(ANDROID_BUFFER_QUEUE_LENGTH)
+{
+}
+
+// Destructor
+OpenSLLayer::~OpenSLLayer()
+{
+    stopStream();
+}
+
+//#define RECORD_AUDIO_TODISK
+#ifdef RECORD_AUDIO_TODISK
+#include <fstream>
+std::ofstream opensl_outfile;
+std::ofstream opensl_infile;
+#endif
+
+void
+OpenSLLayer::startStream()
+{
+    if (isStarted_)
+        return;
+
+    DEBUG("Start OpenSL audio layer");
+
+    if (audioThread_ == NULL) {
+#ifdef RECORD_AUDIO_TODISK
+        opensl_outfile.open("/data/data/com.savoirfairelinux.sflphone/opensl_playback.raw", std::ofstream::out | std::ofstream::binary);
+        opensl_infile.open("/data/data/com.savoirfairelinux.sflphone/opensl_record.raw", std::ofstream::out | std::ofstream::binary);
+#endif
+
+        audioThread_ = new OpenSLThread(this);
+        isStarted_ = true;
+        audioThread_->start();
+    }
+
+}
+
+void
+OpenSLLayer::stopStream()
+{
+    if (not isStarted_)
+        return;
+
+    DEBUG("Stop OpenSL audio layer");
+
+    stopAudioPlayback();
+    stopAudioCapture();
+
+    isStarted_ = false;
+
+    delete audioThread_;
+    audioThread_ = NULL;
+#ifdef RECORD_AUDIO_TODISK
+    opensl_outfile.close();
+    opensl_infile.close();
+#endif
+}
+
+void
+OpenSLLayer::initAudioEngine()
+{
+    SLresult result;
+
+    DEBUG("Create Audio Engine\n");
+    result = slCreateEngine(&engineObject_, 0, NULL, 0, NULL, NULL);
+    assert(SL_RESULT_SUCCESS == result);
+
+    DEBUG("Realize Audio Engine\n");
+    result = (*engineObject_)->Realize(engineObject_, SL_BOOLEAN_FALSE);
+    assert(SL_RESULT_SUCCESS == result);
+
+    DEBUG("Create Audio Engine Interface\n");
+    result = (*engineObject_)->GetInterface(engineObject_, SL_IID_ENGINE, &engineInterface_);
+    assert(SL_RESULT_SUCCESS == result);
+
+    DEBUG("Create Output Mixer\n");
+    result = (*engineInterface_)->CreateOutputMix(engineInterface_, &outputMixer_, 0, NULL, NULL);
+    assert(SL_RESULT_SUCCESS == result);
+
+    DEBUG("Realize Output Mixer\n");
+    result = (*outputMixer_)->Realize(outputMixer_, SL_BOOLEAN_FALSE);
+    assert(SL_RESULT_SUCCESS == result);
+
+    DEBUG("Audio Engine Initialization Done\n");
+}
+
+void
+OpenSLLayer::shutdownAudioEngine()
+{
+
+    // destroy buffer queue audio player object, and invalidate all associated interfaces
+    DEBUG("Shutdown audio player\n");
+
+    if (playerObject_ != NULL) {
+        (*playerObject_)->Destroy(playerObject_);
+        playerObject_ = NULL;
+        playerInterface_ = NULL;
+        playbackBufferQueue_ = NULL;
+    }
+
+    // destroy output mix object, and invalidate all associated interfaces
+    DEBUG("Shutdown audio mixer\n");
+
+    if (outputMixer_ != NULL) {
+        (*outputMixer_)->Destroy(outputMixer_);
+        outputMixer_ = NULL;
+    }
+
+    // destroy engine object, and invalidate all associated interfaces
+    DEBUG("Shutdown audio engine\n");
+
+    if (engineObject_ != NULL) {
+        (*engineObject_)->Destroy(engineObject_);
+        engineObject_ = NULL;
+        engineInterface_ = NULL;
+    }
+}
+
+void
+OpenSLLayer::initAudioPlayback()
+{
+    assert(NULL != engineObject_);
+    assert(NULL != engineInterface_);
+    assert(NULL != outputMixer_);
+
+    SLresult result;
+
+    // Initialize the location of the buffer queue
+    DEBUG("Create playback queue\n");
+    SLDataLocator_AndroidSimpleBufferQueue bufferLocation = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
+                                           NB_BUFFER_PLAYBACK_QUEUE
+                                                            };
+
+    // Initnialize the audio format for this queue
+    DEBUG("Setting audio format\n");
+    SLDataFormat_PCM audioFormat = {SL_DATAFORMAT_PCM, 1,
+                                    SL_SAMPLINGRATE_8,
+                                    SL_PCMSAMPLEFORMAT_FIXED_16,
+                                    SL_PCMSAMPLEFORMAT_FIXED_16,
+                                    SL_SPEAKER_FRONT_CENTER,
+                                    SL_BYTEORDER_LITTLEENDIAN
+                                   };
+
+    // Create the audio source
+    DEBUG("Set Audio Sources\n");
+    SLDataSource audioSource = {&bufferLocation, &audioFormat};
+
+    // Cofiguration fo the audio sink as an output mixer
+    DEBUG("Set output mixer location\n");
+    SLDataLocator_OutputMix mixerLocation = {SL_DATALOCATOR_OUTPUTMIX, outputMixer_};
+    SLDataSink audioSink = {&mixerLocation, NULL};
+
+    const SLInterfaceID ids[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+                                 SL_IID_VOLUME, SL_IID_ANDROIDCONFIGURATION
+                                };
+    const SLboolean req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
+
+    const unsigned nbInterface = ARRAYSIZE(ids);
+
+    // create audio player
+    DEBUG("Create audio player\n");
+    result = (*engineInterface_)->CreateAudioPlayer(engineInterface_, &playerObject_, &audioSource, &audioSink, nbInterface, ids, req);
+    assert(SL_RESULT_SUCCESS == result);
+
+    SLAndroidConfigurationItf playerConfig;
+    SLint32 streamType = SL_ANDROID_STREAM_VOICE;
+
+    result = (*playerObject_)->GetInterface(playerObject_,
+                                            SL_IID_ANDROIDCONFIGURATION,
+                                            &playerConfig);
+
+    if (result == SL_RESULT_SUCCESS && playerConfig) {
+        result = (*playerConfig)->SetConfiguration(
+                     playerConfig, SL_ANDROID_KEY_STREAM_TYPE,
+                     &streamType, sizeof(SLint32));
+    }
+
+    if (result != SL_RESULT_SUCCESS) {
+        ERROR("Unable to set android player configuration");
+    }
+
+    DEBUG("Realize audio player\n");
+    result = (*playerObject_)->Realize(playerObject_, SL_BOOLEAN_FALSE);
+    assert(SL_RESULT_SUCCESS == result);
+
+    // create audio interface
+    DEBUG("Create audio player interface\n");
+    result = (*playerObject_)->GetInterface(playerObject_, SL_IID_PLAY, &playerInterface_);
+    assert(SL_RESULT_SUCCESS == result);
+
+    // create the buffer queue interface
+    DEBUG("Create buffer queue interface\n");
+    result = (*playerObject_)->GetInterface(playerObject_, SL_IID_BUFFERQUEUE, &playbackBufferQueue_);
+    assert(SL_RESULT_SUCCESS == result);
+
+    // register the buffer queue on the buffer object
+    DEBUG("Register audio callback\n");
+    result = (*playbackBufferQueue_)->RegisterCallback(playbackBufferQueue_, audioPlaybackCallback, this);
+    assert(SL_RESULT_SUCCESS == result);
+
+    DEBUG("Audio Playback Initialization Done\n");
+}
+
+void
+OpenSLLayer::initAudioCapture()
+{
+    SLresult result;
+
+    // configure audio source
+    DEBUG("Configure audio source\n");
+    SLDataLocator_IODevice deviceLocator = {SL_DATALOCATOR_IODEVICE,
+                                            SL_IODEVICE_AUDIOINPUT,
+                                            SL_DEFAULTDEVICEID_AUDIOINPUT,
+                                            NULL
+                                           };
+
+    SLDataSource audioSource = {&deviceLocator,
+                                NULL
+                               };
+
+    // configure audio sink
+    DEBUG("Configure audio sink\n");
+
+    SLDataLocator_AndroidSimpleBufferQueue bufferLocator = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
+                                           NB_BUFFER_CAPTURE_QUEUE
+                                                           };
+
+    SLDataFormat_PCM audioFormat = {SL_DATAFORMAT_PCM, 1,
+                                    SL_SAMPLINGRATE_8,
+                                    SL_PCMSAMPLEFORMAT_FIXED_16,
+                                    SL_PCMSAMPLEFORMAT_FIXED_16,
+                                    SL_SPEAKER_FRONT_CENTER,
+                                    SL_BYTEORDER_LITTLEENDIAN
+                                   };
+
+    SLDataSink audioSink = {&bufferLocator,
+                            &audioFormat
+                           };
+
+    // create audio recorder
+    // (requires the RECORD_AUDIO permission)
+    DEBUG("Create audio recorder\n");
+    const SLInterfaceID id[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
+    const SLboolean req[] = {SL_BOOLEAN_TRUE};
+
+    if (engineInterface_ != NULL) {
+        result = (*engineInterface_)->CreateAudioRecorder(engineInterface_,
+                 &recorderObject_, &audioSource, &audioSink, 1, id, req);
+    }
+
+    if (SL_RESULT_SUCCESS != result) {
+        DEBUG("Error: could not create audio recorder");
+        return;
+    }
+
+    // realize the audio recorder
+    DEBUG("Realize the audio recorder\n");
+    result = (*recorderObject_)->Realize(recorderObject_, SL_BOOLEAN_FALSE);
+
+    if (SL_RESULT_SUCCESS != result) {
+        DEBUG("Error: could not realize audio recorder");
+        return;
+    }
+
+    // get the record interface
+    DEBUG("Create the record interface\n");
+    result = (*recorderObject_)->GetInterface(recorderObject_, SL_IID_RECORD, &recorderInterface_);
+    assert(SL_RESULT_SUCCESS == result);
+
+    // get the buffer queue interface
+    DEBUG("Create the buffer queue interface\n");
+    result = (*recorderObject_)->GetInterface(recorderObject_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+             &recorderBufferQueue_);
+    assert(SL_RESULT_SUCCESS == result);
+
+    // register callback on the buffer queue
+    DEBUG("Register the audio capture callback\n");
+    result = (*recorderBufferQueue_)->RegisterCallback(recorderBufferQueue_, audioCaptureCallback, this);
+    assert(SL_RESULT_SUCCESS == result);
+
+    DEBUG("Audio capture initialized\n");
+}
+
+
+void
+OpenSLLayer::startAudioPlayback()
+{
+    assert(NULL != playbackBufferQueue_);
+
+    DEBUG("Start audio playback\n");
+
+    SLresult result;
+
+    for (int i = 0; i < NB_BUFFER_PLAYBACK_QUEUE; i++) {
+        AudioBuffer &buffer = getNextPlaybackBuffer();
+        incrementPlaybackIndex();
+
+        buffer.reset();
+
+        result = (*playbackBufferQueue_)->Enqueue(playbackBufferQueue_, buffer.data(), buffer.size());
+
+        if (SL_RESULT_SUCCESS != result) {
+            DEBUG("Error could not enqueue initial buffers\n");
+        }
+    }
+
+    result = (*playerInterface_)->SetPlayState(playerInterface_, SL_PLAYSTATE_PLAYING);
+    assert(SL_RESULT_SUCCESS == result);
+
+    DEBUG("Audio playback started\n");
+}
+
+void
+OpenSLLayer::startAudioCapture()
+{
+    assert(NULL != playbackBufferQueue_);
+
+    DEBUG("Start audio capture\n");
+
+    SLresult result;
+
+
+    // in case already recording, stop recording and clear buffer queue
+    if (recorderInterface_ != NULL) {
+        result = (*recorderInterface_)->SetRecordState(recorderInterface_, SL_RECORDSTATE_STOPPED);
+        assert(SL_RESULT_SUCCESS == result);
+    }
+
+    DEBUG("Clearing recorderBufferQueue\n");
+    result = (*recorderBufferQueue_)->Clear(recorderBufferQueue_);
+    assert(SL_RESULT_SUCCESS == result);
+
+    DEBUG("getting next record buffer\n");
+    // enqueue an empty buffer to be filled by the recorder
+    // (for streaming recording, we enqueue at least 2 empty buffers to start things off)
+    AudioBuffer &buffer = getNextRecordBuffer();
+    incrementRecordIndex();
+
+    buffer.reset();
+
+    DEBUG("Enqueue record buffer\n");
+    result = (*recorderBufferQueue_)->Enqueue(recorderBufferQueue_, buffer.data(), buffer.size());
+
+    // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
+    // which for this code example would indicate a programming error
+    if (SL_RESULT_SUCCESS != result) {
+        DEBUG("Error could not enqueue buffers in audio capture\n");
+        return;
+    }
+
+    // start recording
+    result = (*recorderInterface_)->SetRecordState(recorderInterface_, SL_RECORDSTATE_RECORDING);
+    assert(SL_RESULT_SUCCESS == result);
+
+    DEBUG("Audio capture started\n");
+}
+
+void
+OpenSLLayer::stopAudioPlayback()
+{
+    DEBUG("Stop audio playback\n");
+
+    if (playerInterface_ != NULL) {
+        SLresult result;
+        result = (*playerInterface_)->SetPlayState(playerInterface_, SL_PLAYSTATE_STOPPED);
+        assert(SL_RESULT_SUCCESS == result);
+    }
+
+    DEBUG("Audio playback stopped\n");
+}
+
+void
+OpenSLLayer::stopAudioCapture()
+{
+    DEBUG("Stop audio capture\n");
+
+    if (recorderInterface_ != NULL) {
+        SLresult result;
+        result = (*recorderInterface_)->SetRecordState(recorderInterface_, SL_RECORDSTATE_STOPPED);
+        assert(SL_RESULT_SUCCESS == result);
+    }
+
+    DEBUG("Audio capture stopped\n");
+
+}
+
+std::vector<std::string>
+OpenSLLayer::getCaptureDeviceList() const
+{
+    std::vector<std::string> captureDeviceList;
+
+    return captureDeviceList;
+}
+
+std::vector<std::string>
+OpenSLLayer::getPlaybackDeviceList() const
+{
+    std::vector<std::string> playbackDeviceList;
+
+    return playbackDeviceList;
+}
+
+void
+OpenSLLayer::playback(SLAndroidSimpleBufferQueueItf queue)
+{
+    assert(NULL != queue);
+
+    usleep(20000);
+
+    AudioBuffer &buffer = getNextPlaybackBuffer();
+
+    buffer.reset();
+
+    const bool bufferFilled = audioPlaybackFillBuffer(buffer);
+
+    if (bufferFilled) {
+#ifdef RECORD_AUDIO_TODISK
+        opensl_outfile.write((char const *)(buffer.data()), buffer.size());
+#endif
+        SLresult result = (*queue)->Enqueue(queue, buffer.data(), buffer.size());
+
+        if (SL_RESULT_SUCCESS != result) {
+            DEBUG("Error could not enqueue buffers in playback callback\n");
+        }
+
+        incrementPlaybackIndex();
+    }
+}
+
+void
+OpenSLLayer::audioPlaybackCallback(SLAndroidSimpleBufferQueueItf queue, void *context)
+{
+    assert(NULL != context);
+    static_cast<OpenSLLayer*>(context)->playback(queue);
+}
+
+void
+OpenSLLayer::capture(SLAndroidSimpleBufferQueueItf queue)
+{
+    assert(NULL != queue);
+
+    AudioBuffer &buffer = getNextRecordBuffer();
+    incrementRecordIndex();
+
+    SLresult result;
+
+    // enqueue an empty buffer to be filled by the recorder
+    // (for streaming recording, we enqueue at least 2 empty buffers to start things off)
+    result = (*recorderBufferQueue_)->Enqueue(recorderBufferQueue_, buffer.data(), buffer.size());
+    // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
+    // which for this code example would indicate a programming error
+    assert(SL_RESULT_SUCCESS == result);
+
+    audioCaptureFillBuffer(buffer);
+#ifdef RECORD_AUDIO_TODISK
+    opensl_infile.write((char const *)(buffer.data()), buffer.size());
+#endif
+}
+
+void
+OpenSLLayer::audioCaptureCallback(SLAndroidSimpleBufferQueueItf queue, void *context)
+{
+    assert(NULL != context);
+    static_cast<OpenSLLayer*>(context)->capture(queue);
+}
+
+
+void
+OpenSLLayer::updatePreference(AudioPreference &preference, int index, PCMType type)
+{
+#ifdef OUTSIDE_TESTING
+
+    switch (type) {
+        case SFL_PCM_PLAYBACK:
+            break;
+
+        case SFL_PCM_CAPTURE:
+            break;
+
+        case SFL_PCM_RINGTONE:
+            break;
+
+        default:
+            break;
+    }
+
+#endif
+}
+
+bool OpenSLLayer::audioPlaybackFillBuffer(AudioBuffer &buffer)
+{
+    // Looks if there's any voice audio from rtp to be played
+    MainBuffer &mbuffer = Manager::instance().getMainBuffer();
+    size_t bytesToGet = mbuffer.availableForGet(MainBuffer::DEFAULT_ID);
+    size_t urgentBytesToGet = urgentRingBuffer_.availableForGet(MainBuffer::DEFAULT_ID);
+
+
+    PlaybackMode mode = getPlaybackMode();
+
+    bool bufferFilled = false;
+
+    switch (mode) {
+        case NONE:
+        case TONE:
+        case RINGTONE:
+        case URGENT: {
+            if (urgentBytesToGet > 0)
+                bufferFilled = audioPlaybackFillWithUrgent(buffer, urgentBytesToGet);
+            else
+                bufferFilled = audioPlaybackFillWithToneOrRingtone(buffer);
+        }
+        break;
+
+        case VOICE: {
+            if (bytesToGet > 0)
+                bufferFilled = audioPlaybackFillWithVoice(buffer, bytesToGet);
+            else {
+                buffer.reset();
+                bufferFilled = true;
+            }
+        }
+        break;
+
+        case ZEROS:
+        default: {
+            buffer.reset();
+            bufferFilled = true;
+        }
+    }
+
+    if (!bufferFilled)
+        printf("Error buffer not filled in audio playback\n");
+
+    return bufferFilled;
+}
+
+// #define RECORD_TOMAIN_TODISK
+#ifdef RECORD_TOMAIN_TODISK
+#include <fstream>
+std::ofstream opensl_tomainbuffer("/data/data/com.savoirfairelinux.sflphone/opensl_tomain.raw", std::ofstream::out | std::ofstream::binary);
+#endif
+
+void OpenSLLayer::audioCaptureFillBuffer(AudioBuffer &buffer)
+{
+    MainBuffer &mbuffer = Manager::instance().getMainBuffer();
+
+    const unsigned mainBufferSampleRate = mbuffer.getInternalSamplingRate();
+    const bool resample = mainBufferSampleRate != sampleRate_;
+
+    buffer.applyGain(captureGain_);
+
+    if (resample) {
+        AudioBuffer out(buffer);
+        out.setSampleRate(sampleRate_);
+
+        converter_.resample(buffer, out);
+        dcblocker_.process(out);
+        mbuffer.putData(out, MainBuffer::DEFAULT_ID);
+    } else {
+        dcblocker_.process(buffer);
+#ifdef RECORD_TOMAIN_TODISK
+        opensl_tomainbuffer.write((char const *)in_ptr, toGetBytes /);
+#endif
+        mbuffer.putData(buffer, MainBuffer::DEFAULT_ID);
+    }
+}
+
+bool OpenSLLayer::audioPlaybackFillWithToneOrRingtone(AudioBuffer &buffer)
+{
+    AudioLoop *tone = Manager::instance().getTelephoneTone();
+    AudioLoop *file_tone = Manager::instance().getTelephoneFile();
+
+    // In case of a dtmf, the pointers will be set to NULL once the dtmf length is
+    // reached. For this reason we need to fill audio buffer with zeros if pointer is NULL
+    if (tone) {
+        tone->getNext(buffer, playbackGain_);
+    } else if (file_tone) {
+        file_tone->getNext(buffer, playbackGain_);
+    } else {
+        buffer.reset();
+    }
+
+    return true;
+}
+
+bool OpenSLLayer::audioPlaybackFillWithUrgent(AudioBuffer &buffer, size_t bytesToGet)
+{
+    // Urgent data (dtmf, incoming call signal) come first.
+    bytesToGet = std::min(bytesToGet, buffer.capacity());
+    urgentRingBuffer_.get(buffer, MainBuffer::DEFAULT_ID);
+    buffer.applyGain(playbackGain_);
+
+    // Consume the regular one as well (same amount of bytes)
+    Manager::instance().getMainBuffer().discard(bytesToGet, MainBuffer::DEFAULT_ID);
+
+    return true;
+}
+
+bool OpenSLLayer::audioPlaybackFillWithVoice(AudioBuffer &buffer, size_t bytesAvail)
+{
+    const size_t bytesToCpy = buffer.capacity();
+
+    if (bytesAvail == 0)
+        return false;
+
+    MainBuffer &mainBuffer = Manager::instance().getMainBuffer();
+
+    mainBuffer.getData(buffer, MainBuffer::DEFAULT_ID);
+    buffer.applyGain(getPlaybackGain());
+
+    if (sampleRate_ != mainBuffer.getInternalSamplingRate()) {
+        AudioBuffer out(buffer, false);
+        out.setSampleRate(sampleRate_);
+        converter_.resample(buffer, out);
+        buffer = out;
+    }
+
+    return true;
+}
diff --git a/daemon/src/audio/opensl/opensllayer.h b/daemon/src/audio/opensl/opensllayer.h
new file mode 100644
index 0000000000000000000000000000000000000000..889137503af884fabb107f0a662f4489a90904d4
--- /dev/null
+++ b/daemon/src/audio/opensl/opensllayer.h
@@ -0,0 +1,268 @@
+/*
+ *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
+ *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *
+ *  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, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#ifndef _OPENSL_LAYER_H
+#define _OPENSL_LAYER_H
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+#include <vector>
+
+#include "../audiolayer.h"
+
+
+enum PCMType {
+    SFL_PCM_BOTH = 0x0021,          /** To open both playback and capture devices */
+    SFL_PCM_PLAYBACK = 0x0022,      /** To open playback device only */
+    SFL_PCM_CAPTURE = 0x0023,       /** To open capture device only */
+    SFL_PCM_RINGTONE = 0x0024       /** To open the ringtone device only */
+};
+
+class AudioPreference;
+
+#include "noncopyable.h"
+
+class OpenSLThread;
+
+#define ANDROID_BUFFER_QUEUE_LENGTH 2
+
+
+/**
+ * @file  OpenSLLayer.h
+ * @brief Main sound class for android. Manages the data transfers between the application and the hardware.
+ */
+
+class OpenSLLayer : public AudioLayer {
+    public:
+        /**
+         * Constructor
+         */
+        OpenSLLayer();
+
+        /**
+         * Destructor
+         */
+        ~OpenSLLayer();
+
+        /**
+         * Start the capture stream and prepare the playback stream.
+         * The playback starts accordingly to its threshold
+         */
+        virtual void startStream();
+
+        /**
+         * Stop the playback and capture streams.
+         * Drops the pending frames and put the capture and playback handles to PREPARED state
+         */
+        virtual void stopStream();
+
+        /**
+         * Scan the sound card available for capture on the system
+         * @return std::vector<std::string> The vector containing the string description of the card
+         */
+        virtual std::vector<std::string> getCaptureDeviceList() const;
+
+        /**
+         * Scan the sound card available for capture on the system
+         * @return std::vector<std::string> The vector containing the string description of the card
+         */
+        virtual std::vector<std::string> getPlaybackDeviceList() const;
+
+        void initAudioEngine();
+
+        void shutdownAudioEngine();
+
+        void initAudioPlayback();
+
+        void initAudioCapture();
+
+        void startAudioPlayback();
+
+        void startAudioCapture();
+
+        void stopAudioPlayback();
+
+        void stopAudioCapture();
+
+        virtual int getAudioDeviceIndex(const std::string&) const {
+            return 0;
+        }
+
+        virtual std::string getAudioDeviceName(int, AudioLayer::PCMType) const {
+            return "";
+        }
+
+    private:
+
+        bool audioBufferFillWithZeros(AudioBuffer &buffer);
+
+        /**
+         * Here fill the input buffer with tone or ringtone samples
+         */
+        bool audioPlaybackFillWithToneOrRingtone(AudioBuffer &buffer);
+
+        bool audioPlaybackFillWithUrgent(AudioBuffer &buffer, size_t bytesAvail);
+
+        bool audioPlaybackFillWithVoice(AudioBuffer &buffer, size_t bytesAvail);
+
+        /**
+         * The main logic to determine what should be played is determined here
+         */
+        bool audioPlaybackFillBuffer(AudioBuffer &buffer);
+
+        void audioCaptureFillBuffer(AudioBuffer &buffer);
+
+
+        /**
+         * This is the main audio playabck callback called by the OpenSL layer
+         */
+        static void audioPlaybackCallback(SLAndroidSimpleBufferQueueItf bq, void *context);
+
+        /**
+         * This is the main audio capture callback called by the OpenSL layer
+         */
+        static void audioCaptureCallback(SLAndroidSimpleBufferQueueItf bq, void *context);
+
+        /**
+         * Get the index of the audio card for capture
+         * @return int The index of the card used for capture
+         *                     0 for the first available card on the system, 1 ...
+         */
+        virtual int getIndexCapture() const {
+            return indexIn_;
+        }
+
+        /**
+         * Get the index of the audio card for playback
+         * @return int The index of the card used for playback
+         *                     0 for the first available card on the system, 1 ...
+         */
+        virtual int getIndexPlayback() const {
+            return indexOut_;
+        }
+
+        /**
+         * Get the index of the audio card for ringtone (could be differnet from playback)
+         * @return int The index of the card used for ringtone
+         *                 0 for the first available card on the system, 1 ...
+         */
+        virtual int getIndexRingtone() const {
+            return indexRing_;
+        }
+
+        AudioBuffer &getNextPlaybackBuffer(void) {
+            return playbackBufferStack_[playbackBufferIndex_];
+        }
+
+        AudioBuffer &getNextRecordBuffer(void) {
+            return recordBufferStack_[recordBufferIndex_];
+        }
+
+        void incrementPlaybackIndex(void) {
+            playbackBufferIndex_ = (playbackBufferIndex_ + 1) % NB_BUFFER_PLAYBACK_QUEUE;
+        }
+
+        void incrementRecordIndex(void) {
+            recordBufferIndex_ = (recordBufferIndex_ + 1) % NB_BUFFER_CAPTURE_QUEUE;
+        }
+
+        void playback(SLAndroidSimpleBufferQueueItf queue);
+        void capture(SLAndroidSimpleBufferQueueItf queue);
+        friend class OpenSLThread;
+
+        static const int NB_BUFFER_PLAYBACK_QUEUE;
+
+        static const int NB_BUFFER_CAPTURE_QUEUE;
+
+        /**
+         * Number of audio cards on which capture stream has been opened
+         */
+        int indexIn_;
+
+        /**
+         * Number of audio cards on which playback stream has been opened
+         */
+        int indexOut_;
+
+        /**
+         * Number of audio cards on which ringtone stream has been opened
+         */
+        int indexRing_;
+
+        NON_COPYABLE(OpenSLLayer);
+
+        virtual void updatePreference(AudioPreference &pref, int index, PCMType type);
+
+        OpenSLThread *audioThread_;
+
+        bool isStarted_;
+
+        /**
+         * OpenSL standard object interface
+         */
+        SLObjectItf engineObject_;
+
+        /**
+         * OpenSL sound engine interface
+         */
+        SLEngineItf engineInterface_;
+
+        /**
+         * Output mix interface
+         */
+        SLObjectItf outputMixer_;
+
+        SLObjectItf playerObject_;
+
+        SLObjectItf recorderObject_;
+
+        /**
+         *
+         */
+        SLPlayItf playerInterface_;
+
+        SLRecordItf recorderInterface_;
+
+        /**
+         * OpenSL playback buffer
+         */
+        SLAndroidSimpleBufferQueueItf playbackBufferQueue_;
+
+        SLAndroidSimpleBufferQueueItf recorderBufferQueue_;
+
+        int playbackBufferIndex_;
+
+        int recordBufferIndex_;
+
+        AudioBufferStack playbackBufferStack_;
+        AudioBufferStack recordBufferStack_;
+};
+
+#endif // _OPENSL_LAYER_H_
diff --git a/daemon/src/audio/pulseaudio/audiostream.cpp b/daemon/src/audio/pulseaudio/audiostream.cpp
index fe53f98409096387d655a6e0941f1ff6f4c8a2b9..97d7deef5929ff75a24216df43df0e321c8aa3ca 100644
--- a/daemon/src/audio/pulseaudio/audiostream.cpp
+++ b/daemon/src/audio/pulseaudio/audiostream.cpp
@@ -38,20 +38,19 @@ AudioStream::AudioStream(pa_context *c,
                          const char *desc,
                          int type,
                          unsigned samplrate,
-                         const std::string &deviceName)
+                         const PaDeviceInfos* infos)
     : audiostream_(0), mainloop_(m)
 {
-    static const pa_channel_map channel_map = {
-        1,
-        { PA_CHANNEL_POSITION_MONO },
-    };
+    const pa_channel_map channel_map = infos->channel_map;
 
     pa_sample_spec sample_spec = {
         PA_SAMPLE_S16LE, // PA_SAMPLE_FLOAT32LE,
         samplrate,
-        1
+        channel_map.channels
     };
 
+    DEBUG("%s: trying to create stream with device %s (%dHz, %d channels)", desc, infos->name.c_str(), samplrate, channel_map.channels);
+
     assert(pa_sample_spec_valid(&sample_spec));
     assert(pa_channel_map_valid(&channel_map));
 
@@ -70,18 +69,17 @@ AudioStream::AudioStream(pa_context *c,
     attributes.minreq = (uint32_t) -1;
 
     pa_threaded_mainloop_lock(mainloop_);
-    const pa_stream_flags_t flags = static_cast<pa_stream_flags_t>(PA_STREAM_ADJUST_LATENCY |
-                                                                   PA_STREAM_AUTO_TIMING_UPDATE);
+    const pa_stream_flags_t flags = static_cast<pa_stream_flags_t>(PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE);
 
     if (type == PLAYBACK_STREAM || type == RINGTONE_STREAM) {
         pa_stream_connect_playback(audiostream_,
-                                   deviceName.empty() ? NULL : deviceName.c_str(),
+                                   infos->name.empty() ? NULL : infos->name.c_str(),
                                    &attributes,
                                    flags,
                                    NULL, NULL);
     } else if (type == CAPTURE_STREAM) {
         pa_stream_connect_record(audiostream_,
-                                 deviceName.empty() ? NULL : deviceName.c_str(),
+                                 infos->name.empty() ? NULL : infos->name.c_str(),
                                  &attributes,
                                  flags);
     }
diff --git a/daemon/src/audio/pulseaudio/audiostream.h b/daemon/src/audio/pulseaudio/audiostream.h
index ec782beb3f0282aa5fef6860109f774888446c1d..650a9bc20ca1e4cdd0465a7034cff62f204c0b2b 100644
--- a/daemon/src/audio/pulseaudio/audiostream.h
+++ b/daemon/src/audio/pulseaudio/audiostream.h
@@ -34,6 +34,7 @@
 #include <pulse/pulseaudio.h>
 #include <string>
 #include "noncopyable.h"
+#include "pulselayer.h"
 
 /**
  * This data structure contains the different king of audio streams available
@@ -53,9 +54,9 @@ class AudioStream {
          * @param description
          * @param types
          * @param audio sampling rate
-         * @param device name
+         * @param pointer to pa_source_info or pa_sink_info (depending on type).
          */
-        AudioStream(pa_context *, pa_threaded_mainloop *, const char *, int, unsigned, const std::string&);
+        AudioStream(pa_context *, pa_threaded_mainloop *, const char *, int, unsigned, const PaDeviceInfos*);
 
         ~AudioStream();
 
@@ -67,6 +68,18 @@ class AudioStream {
             return audiostream_;
         }
 
+        const pa_sample_spec *sampleSpec() {
+            return pa_stream_get_sample_spec(audiostream_);
+        }
+
+        inline size_t sampleSize() {
+            return pa_sample_size(sampleSpec());
+        }
+
+        inline uint8_t channels() {
+            return sampleSpec()->channels;
+        }
+
         bool isReady();
 
     private:
diff --git a/daemon/src/audio/pulseaudio/pulselayer.cpp b/daemon/src/audio/pulseaudio/pulselayer.cpp
index 8c85d08bdfd2cf7419d4623898e70da1f4029e77..26f59c0b159e1546a90d43f883854f5f1142d6c7 100644
--- a/daemon/src/audio/pulseaudio/pulselayer.cpp
+++ b/daemon/src/audio/pulseaudio/pulselayer.cpp
@@ -3,6 +3,7 @@
  *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
  *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
  *  Author: Андрей Лухнов <aol.nnov@gmail.com>
+ *  Author: Adrien Beraud <adrien.beraud@gmail.com>
  *
  *  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
@@ -32,6 +33,7 @@
 
 #include <algorithm> // for std::find
 #include <stdexcept>
+
 #include "audiostream.h"
 #include "pulselayer.h"
 #include "audio/samplerateconverter.h"
@@ -39,6 +41,7 @@
 #include "logger.h"
 #include "manager.h"
 
+#include <unistd.h>
 #include <cstdlib>
 #include <fstream>
 
@@ -67,7 +70,7 @@ void stream_moved_callback(pa_stream *s, void *userdata UNUSED)
 } // end anonymous namespace
 
 #ifdef RECTODISK
-std::ofstream outfileResampled ("testMicOuputResampled.raw", std::ifstream::binary);
+std::ofstream outfileResampled("testMicOuputResampled.raw", std::ifstream::binary);
 std::ofstream outfile("testMicOuput.raw", std::ifstream::binary);
 #endif
 
@@ -77,20 +80,29 @@ PulseLayer::PulseLayer(AudioPreference &pref)
     , ringtone_(0)
     , sinkList_()
     , sourceList_()
-    , mic_buffer_(0)
-    , mic_buf_size_(0)
+    , mic_buffer_()
     , context_(0)
     , mainloop_(pa_threaded_mainloop_new())
     , enumeratingSinks_(false)
     , enumeratingSources_(false)
     , preference_(pref)
 {
-    setenv("PULSE_PROP_media.role", "phone", 1);
-
     if (!mainloop_)
         throw std::runtime_error("Couldn't create pulseaudio mainloop");
 
-    context_ = pa_context_new(pa_threaded_mainloop_get_api(mainloop_) , "SFLphone");
+#if PA_CHECK_VERSION(1, 0, 0)
+    pa_proplist *pl = pa_proplist_new();
+    pa_proplist_sets(pl, PA_PROP_MEDIA_ROLE, "phone");
+
+    context_ = pa_context_new_with_proplist(pa_threaded_mainloop_get_api(mainloop_), "SFLphone", pl);
+
+    if (pl)
+        pa_proplist_free(pl);
+
+#else
+    setenv("PULSE_PROP_media.role", "phone", 1);
+    context_ = pa_context_new(pa_threaded_mainloop_get_api(mainloop_), "SFLphone");
+#endif
 
     if (!context_)
         throw std::runtime_error("Couldn't create pulseaudio context");
@@ -134,8 +146,6 @@ PulseLayer::~PulseLayer()
 
     if (mainloop_)
         pa_threaded_mainloop_free(mainloop_);
-
-    delete [] mic_buffer_;
 }
 
 void PulseLayer::context_state_callback(pa_context* c, void *user_data)
@@ -143,7 +153,7 @@ void PulseLayer::context_state_callback(pa_context* c, void *user_data)
     PulseLayer *pulse = static_cast<PulseLayer*>(user_data);
     assert(c and pulse and pulse->mainloop_);
     const pa_subscription_mask_t mask = (pa_subscription_mask_t)
-        (PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE);
+                                        (PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE);
 
     switch (pa_context_get_state(c)) {
         case PA_CONTEXT_CONNECTING:
@@ -179,6 +189,7 @@ void PulseLayer::updateSinkList()
     sinkList_.clear();
     enumeratingSinks_ = true;
     pa_operation *op = pa_context_get_sink_info_list(context_, sink_input_info_callback, this);
+
     if (op != NULL)
         pa_operation_unref(op);
 }
@@ -188,47 +199,72 @@ void PulseLayer::updateSourceList()
     sourceList_.clear();
     enumeratingSources_ = true;
     pa_operation *op = pa_context_get_source_info_list(context_, source_input_info_callback, this);
+
     if (op != NULL)
         pa_operation_unref(op);
 }
 
-bool PulseLayer::inSinkList(const std::string &deviceName) const
+bool PulseLayer::inSinkList(const std::string &deviceName)
 {
-    const bool found = std::find(sinkList_.begin(), sinkList_.end(), deviceName) != sinkList_.end();
+    const bool found = std::find_if(sinkList_.begin(), sinkList_.end(), PaDeviceInfos::nameComparator(deviceName)) != sinkList_.end();
+
     DEBUG("seeking for %s in sinks. %s found", deviceName.c_str(), found ? "" : "NOT");
     return found;
 }
 
-
-bool PulseLayer::inSourceList(const std::string &deviceName) const
+bool PulseLayer::inSourceList(const std::string &deviceName)
 {
-    const bool found = std::find(sourceList_.begin(), sourceList_.end(), deviceName) != sourceList_.end();
+    const bool found = std::find_if(sourceList_.begin(), sourceList_.end(), PaDeviceInfos::nameComparator(deviceName)) != sourceList_.end();
+
     DEBUG("seeking for %s in sources. %s found", deviceName.c_str(), found ? "" : "NOT");
     return found;
 }
 
 std::vector<std::string> PulseLayer::getCaptureDeviceList() const
 {
-    return sourceList_;
+    const unsigned n = sourceList_.size();
+    std::vector<std::string> names(n);
+
+    for (unsigned i = 0; i < n; i++)
+        names[i] = sourceList_[i].name;
+
+    return names;
 }
 
 std::vector<std::string> PulseLayer::getPlaybackDeviceList() const
 {
-    return sinkList_;
+    const unsigned n = sinkList_.size();
+    std::vector<std::string> names(n);
+
+    for (unsigned i = 0; i < n; i++)
+        names[i] = sinkList_[i].name;
+
+    return names;
 }
 
 int PulseLayer::getAudioDeviceIndex(const std::string& name) const
 {
-    int index = std::distance(sourceList_.begin(), std::find(sourceList_.begin(), sourceList_.end(), name));
+    int index = std::distance(sourceList_.begin(), std::find_if(sourceList_.begin(), sourceList_.end(), PaDeviceInfos::nameComparator(name)));
+
     if (index == std::distance(sourceList_.begin(), sourceList_.end())) {
-        // not found in sources, search in sinks then
-        index = std::distance(sinkList_.begin(), std::find(sinkList_.begin(), sinkList_.end(), name));
+        index = std::distance(sinkList_.begin(), std::find_if(sinkList_.begin(), sinkList_.end(), PaDeviceInfos::nameComparator(name)));
     }
+
     return index;
 }
 
+const PaDeviceInfos* PulseLayer::getDeviceInfos(const std::vector<PaDeviceInfos>& list, const std::string& name) const
+{
+    std::vector<PaDeviceInfos>::const_iterator dev_info = std::find_if(list.begin(), list.end(), PaDeviceInfos::nameComparator(name));
+
+    if (dev_info == list.end()) return NULL;
+
+    return &(*dev_info);
+}
+
 std::string PulseLayer::getAudioDeviceName(int index, PCMType type) const
 {
+
     switch (type) {
         case SFL_PCM_PLAYBACK:
         case SFL_PCM_RINGTONE:
@@ -236,13 +272,17 @@ std::string PulseLayer::getAudioDeviceName(int index, PCMType type) const
                 ERROR("Index %d out of range", index);
                 return "";
             }
-            return sinkList_[index];
+
+            return sinkList_[index].name;
+
         case SFL_PCM_CAPTURE:
             if (index < 0 or static_cast<size_t>(index) >= sourceList_.size()) {
                 ERROR("Index %d out of range", index);
                 return "";
             }
-            return sourceList_[index];
+
+            return sourceList_[index].name;
+
         default:
             return "";
     }
@@ -258,23 +298,44 @@ void PulseLayer::createStreams(pa_context* c)
     std::string ringtoneDevice(preference_.getPulseDeviceRingtone());
     std::string defaultDevice = "";
 
-    DEBUG("Devices:\n   playback: %s\n   record: %s\n   ringtone: %s",
-           playbackDevice.c_str(), captureDevice.c_str(), ringtoneDevice.c_str());
+    DEBUG("Devices: playback: %s record: %s ringtone: %s",
+          playbackDevice.c_str(), captureDevice.c_str(), ringtoneDevice.c_str());
+
+    // Create playback stream
+    const PaDeviceInfos* dev_infos = getDeviceInfos(sinkList_, playbackDevice);
 
-    playback_ = new AudioStream(c, mainloop_, "SFLphone playback", PLAYBACK_STREAM, sampleRate_,
-                                inSinkList(playbackDevice) ? playbackDevice : defaultDevice);
+    if (dev_infos == NULL) {
+        dev_infos = &sinkList_[0];
+        DEBUG("Prefered playback device not found in device list, selecting %s instead.", dev_infos->name.c_str());
+    }
+
+    playback_ = new AudioStream(c, mainloop_, "SFLphone playback", PLAYBACK_STREAM, sampleRate_, dev_infos);
 
     pa_stream_set_write_callback(playback_->pulseStream(), playback_callback, this);
     pa_stream_set_moved_callback(playback_->pulseStream(), stream_moved_callback, this);
 
-    record_ = new AudioStream(c, mainloop_, "SFLphone capture", CAPTURE_STREAM, sampleRate_,
-                              inSourceList(captureDevice) ? captureDevice : defaultDevice);
+    // Create capture stream
+    dev_infos = getDeviceInfos(sourceList_, captureDevice);
+
+    if (dev_infos == NULL) {
+        dev_infos = &sourceList_[0];
+        DEBUG("Prefered capture device not found in device list, selecting %s instead.", dev_infos->name.c_str());
+    }
+
+    record_ = new AudioStream(c, mainloop_, "SFLphone capture", CAPTURE_STREAM, sampleRate_, dev_infos);
 
     pa_stream_set_read_callback(record_->pulseStream() , capture_callback, this);
     pa_stream_set_moved_callback(record_->pulseStream(), stream_moved_callback, this);
 
-    ringtone_ = new AudioStream(c, mainloop_, "SFLphone ringtone", RINGTONE_STREAM, sampleRate_,
-                                inSinkList(ringtoneDevice) ? ringtoneDevice : defaultDevice);
+    // Create ringtone stream
+    dev_infos = getDeviceInfos(sinkList_, ringtoneDevice);
+
+    if (dev_infos == NULL) {
+        dev_infos = &sinkList_[0];
+        DEBUG("Prefered ringtone device not found in device list, selecting %s instead.", dev_infos->name.c_str());
+    }
+
+    ringtone_ = new AudioStream(c, mainloop_, "SFLphone ringtone", RINGTONE_STREAM, sampleRate_, dev_infos);
 
     pa_stream_set_write_callback(ringtone_->pulseStream(), ringtone_callback, this);
     pa_stream_set_moved_callback(ringtone_->pulseStream(), stream_moved_callback, this);
@@ -286,13 +347,13 @@ void PulseLayer::createStreams(pa_context* c)
 }
 
 namespace {
-    // Delete stream and zero out its pointer
-    void
-    cleanupStream(AudioStream *&stream)
-    {
-        delete stream;
-        stream = 0;
-    }
+// Delete stream and zero out its pointer
+void
+cleanupStream(AudioStream *&stream)
+{
+    delete stream;
+    stream = 0;
+}
 }
 
 
@@ -338,6 +399,9 @@ void PulseLayer::writeToSpeaker()
         return;
 
     pa_stream *s = playback_->pulseStream();
+    const pa_sample_spec* sample_spec = pa_stream_get_sample_spec(s);
+    size_t sample_size = pa_frame_size(sample_spec);
+    const unsigned n_channels = sample_spec->channels;
 
     // available bytes to be written in pulseaudio internal buffer
     int ret = pa_stream_writable_size(s);
@@ -349,22 +413,29 @@ void PulseLayer::writeToSpeaker()
         return;
 
     size_t writableBytes = ret;
+    const size_t writableSamples = writableBytes / sample_size;
 
     notifyIncomingCall();
 
-    size_t urgentBytes = urgentRingBuffer_.availableForGet(MainBuffer::DEFAULT_ID);
+    size_t urgentSamples = urgentRingBuffer_.availableForGet(MainBuffer::DEFAULT_ID);
+    size_t urgentBytes = urgentSamples * sample_size;
 
-    if (urgentBytes > writableBytes)
-        urgentBytes = writableBytes;
+    if (urgentSamples > writableSamples) {
+        urgentSamples = writableSamples;
+        urgentBytes = urgentSamples * sample_size;
+    }
+
+    SFLAudioSample *data = 0;
 
-    void *data = 0;
     if (urgentBytes) {
-        pa_stream_begin_write(s, &data, &urgentBytes);
-        urgentRingBuffer_.get(data, urgentBytes, MainBuffer::DEFAULT_ID);
-        applyGain(static_cast<SFLDataFormat *>(data), urgentBytes / sizeof(SFLDataFormat), getPlaybackGain());
+        AudioBuffer linearbuff(urgentSamples, n_channels);
+        pa_stream_begin_write(s, (void**)&data, &urgentBytes);
+        urgentRingBuffer_.get(linearbuff, MainBuffer::DEFAULT_ID); // retrive only the first sample_spec->channels channels
+        linearbuff.applyGain(playbackGain_);
+        linearbuff.interleave(data);
         pa_stream_write(s, data, urgentBytes, NULL, 0, PA_SEEK_RELATIVE);
-        // Consume the regular one as well (same amount of bytes)
-        Manager::instance().getMainBuffer().discard(urgentBytes, MainBuffer::DEFAULT_ID);
+        // Consume the regular one as well (same amount of samples)
+        Manager::instance().getMainBuffer().discard(urgentSamples, MainBuffer::DEFAULT_ID);
         return;
     }
 
@@ -374,9 +445,10 @@ void PulseLayer::writeToSpeaker()
 
     if (toneToPlay) {
         if (playback_->isReady()) {
-            pa_stream_begin_write(s, &data, &writableBytes);
-            toneToPlay->getNext((SFLDataFormat*)data, writableBytes / sizeof(SFLDataFormat), 100);
-            applyGain(static_cast<SFLDataFormat *>(data), writableBytes / sizeof(SFLDataFormat), getPlaybackGain());
+            pa_stream_begin_write(s, (void**)&data, &writableBytes);
+            AudioBuffer linearbuff(writableSamples, n_channels);
+            toneToPlay->getNext(linearbuff, playbackGain_); // retrive only n_channels
+            linearbuff.interleave(data);
             pa_stream_write(s, data, writableBytes, NULL, 0, PA_SEEK_RELATIVE);
         }
 
@@ -385,18 +457,15 @@ void PulseLayer::writeToSpeaker()
 
     flushUrgent(); // flush remaining samples in _urgentRingBuffer
 
-    size_t availSamples = Manager::instance().getMainBuffer().availableForGet(MainBuffer::DEFAULT_ID) / sizeof(SFLDataFormat);
+    size_t availSamples = Manager::instance().getMainBuffer().availableForGet(MainBuffer::DEFAULT_ID);
 
     if (availSamples == 0) {
-        pa_stream_begin_write(s, &data, &writableBytes);
+        pa_stream_begin_write(s, (void**)&data, &writableBytes);
         memset(data, 0, writableBytes);
         pa_stream_write(s, data, writableBytes, NULL, 0, PA_SEEK_RELATIVE);
         return;
     }
 
-    // how many samples we can write to the output
-    size_t writableSamples = writableBytes / sizeof(SFLDataFormat);
-
     // how many samples we want to read from the buffer
     size_t readableSamples = writableSamples;
 
@@ -404,30 +473,31 @@ void PulseLayer::writeToSpeaker()
 
     unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer().getInternalSamplingRate();
     bool resample = sampleRate_ != mainBufferSampleRate;
+
     if (resample) {
         resampleFactor = (double) sampleRate_ / mainBufferSampleRate;
         readableSamples = (double) readableSamples / resampleFactor;
     }
 
-    if (readableSamples > availSamples)
-        readableSamples = availSamples;
+    readableSamples = std::min(readableSamples, availSamples);
+    size_t nResampled = (double) readableSamples * resampleFactor;
+    size_t resampledBytes =  nResampled * sample_size;
+
+    pa_stream_begin_write(s, (void**)&data, &resampledBytes);
 
-    size_t readableBytes = readableSamples * sizeof(SFLDataFormat);
-    pa_stream_begin_write(s, &data, &readableBytes);
-    Manager::instance().getMainBuffer().getData(data, readableBytes, MainBuffer::DEFAULT_ID);
+    AudioBuffer linearbuff(readableSamples, n_channels);
+    Manager::instance().getMainBuffer().getData(linearbuff, MainBuffer::DEFAULT_ID);
 
     if (resample) {
-        const size_t nResampled = (double) readableSamples * resampleFactor;
-        size_t resampledBytes =  nResampled * sizeof(SFLDataFormat);
-        SFLDataFormat* rsmpl_out = (SFLDataFormat*) pa_xmalloc(resampledBytes);
-        converter_.resample((SFLDataFormat*)data, rsmpl_out, nResampled,
-                             mainBufferSampleRate, sampleRate_, readableSamples);
-        applyGain(rsmpl_out, nResampled, getPlaybackGain());
-        pa_stream_write(s, rsmpl_out, resampledBytes, NULL, 0, PA_SEEK_RELATIVE);
-        pa_xfree(rsmpl_out);
+        AudioBuffer rsmpl_out(nResampled, 1, sampleRate_);
+        converter_.resample(linearbuff, rsmpl_out);
+        rsmpl_out.applyGain(playbackGain_);
+        rsmpl_out.interleave(data);
+        pa_stream_write(s, data, resampledBytes, NULL, 0, PA_SEEK_RELATIVE);
     } else {
-        applyGain(static_cast<SFLDataFormat *>(data), readableSamples, getPlaybackGain());
-        pa_stream_write(s, data, readableBytes, NULL, 0, PA_SEEK_RELATIVE);
+        linearbuff.applyGain(playbackGain_);
+        linearbuff.interleave(data);
+        pa_stream_write(s, data, resampledBytes, NULL, 0, PA_SEEK_RELATIVE);
     }
 }
 
@@ -439,37 +509,50 @@ void PulseLayer::readFromMic()
     const char *data = NULL;
     size_t bytes;
 
+    size_t sample_size = record_->sampleSize();
+    uint8_t channels = record_->channels();
+
     if (pa_stream_peek(record_->pulseStream() , (const void**) &data , &bytes) < 0 or !data)
         return;
 
+#ifdef RECTODISK
+    outfile.write((const char *)data, bytes);
+#endif
+
+    size_t samples = bytes / sample_size;
+
+    AudioBuffer in(samples, channels, sampleRate_);
+    in.deinterleave((SFLAudioSample*)data, samples, channels);
+
     unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer().getInternalSamplingRate();
     bool resample = sampleRate_ != mainBufferSampleRate;
 
-    if (resample) {
+    /*if (resample) {
         double resampleFactor = (double) sampleRate_ / mainBufferSampleRate;
-        bytes = (double) bytes * resampleFactor;
-    }
-
-    size_t samples = bytes / sizeof(SFLDataFormat);
+        //bytes = (double) bytes * resampleFactor;
+    }*/
 
-    if (bytes > mic_buf_size_) {
+    /*if (bytes > mic_buf_size_) {
         mic_buf_size_ = bytes;
         delete [] mic_buffer_;
-        mic_buffer_ = new SFLDataFormat[samples];
-    }
+        mic_buffer_ = new SFLAudioSample[samples];
+    }*/
+
+    AudioBuffer * out = &in;
 
-#ifdef RECTODISK
-    outfile.write((const char *)data, bytes);
-#endif
     if (resample) {
-        converter_.resample((SFLDataFormat*)data, mic_buffer_, samples, mainBufferSampleRate, sampleRate_, samples);
+        mic_buffer_.setSampleRate(mainBufferSampleRate);
+        //converter_.resample((SFLAudioSample*)data, mic_buffer_, samples, mainBufferSampleRate, sampleRate_, samples);
+        converter_.resample(in, mic_buffer_);
+        out = &mic_buffer_;
     }
 
-    dcblocker_.process(mic_buffer_, (SFLDataFormat*)data, samples);
-    applyGain(mic_buffer_, bytes / sizeof(SFLDataFormat), getCaptureGain());
-    Manager::instance().getMainBuffer().putData(mic_buffer_, bytes, MainBuffer::DEFAULT_ID);
+    dcblocker_.process(*out);
+    out->applyGain(playbackGain_);
+    Manager::instance().getMainBuffer().putData(*out, MainBuffer::DEFAULT_ID);
+
 #ifdef RECTODISK
-    outfileResampled.write((const char *)mic_buffer_, bytes);
+    outfileResampled.write((const char *)out->getChannel(0), out->samples() * sizeof(SFLAudioSample));
 #endif
 
     if (pa_stream_drop(record_->pulseStream()) < 0)
@@ -483,6 +566,7 @@ void PulseLayer::ringtoneToSpeaker()
         return;
 
     pa_stream *s = ringtone_->pulseStream();
+    size_t sample_size = ringtone_->sampleSize();
 
     int writable = pa_stream_writable_size(s);
 
@@ -499,11 +583,13 @@ void PulseLayer::ringtoneToSpeaker()
     AudioLoop *fileToPlay = Manager::instance().getTelephoneFile();
 
     if (fileToPlay) {
-        fileToPlay->getNext((SFLDataFormat *) data, bytes / sizeof(SFLDataFormat), 100);
-        applyGain(static_cast<SFLDataFormat *>(data), bytes / sizeof(SFLDataFormat), getPlaybackGain());
-    }
-    else
+        const unsigned samples = (bytes / sample_size) / ringtone_->channels();
+        AudioBuffer tmp(samples, ringtone_->channels());
+        fileToPlay->getNext(tmp, playbackGain_);
+        tmp.interleave((SFLAudioSample*) data);
+    } else {
         memset(data, 0, bytes);
+    }
 
     pa_stream_write(s, data, bytes, NULL, 0, PA_SEEK_RELATIVE);
 }
@@ -514,8 +600,9 @@ PulseLayer::context_changed_callback(pa_context* c,
                                      uint32_t idx UNUSED, void *userdata)
 {
     PulseLayer *context = static_cast<PulseLayer*>(userdata);
+
     switch (type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
-        pa_operation *op;
+            pa_operation *op;
 
         case PA_SUBSCRIPTION_EVENT_SINK:
             switch (type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) {
@@ -524,11 +611,14 @@ PulseLayer::context_changed_callback(pa_context* c,
                     DEBUG("Updating sink list");
                     context->sinkList_.clear();
                     op = pa_context_get_sink_info_list(c, sink_input_info_callback, userdata);
+
                     if (op != NULL)
                         pa_operation_unref(op);
+
                 default:
                     break;
             }
+
             break;
 
         case PA_SUBSCRIPTION_EVENT_SOURCE:
@@ -538,12 +628,16 @@ PulseLayer::context_changed_callback(pa_context* c,
                     DEBUG("Updating source list");
                     context->sourceList_.clear();
                     op = pa_context_get_source_info_list(c, source_input_info_callback, userdata);
+
                     if (op != NULL)
                         pa_operation_unref(op);
+
                 default:
                     break;
             }
+
             break;
+
         default:
             DEBUG("Unhandled event type 0x%x", type);
             break;
@@ -562,32 +656,34 @@ void PulseLayer::source_input_info_callback(pa_context *c UNUSED, const pa_sourc
     }
 
     DEBUG("Source %u\n"
-           "    Name: %s\n"
-           "    Driver: %s\n"
-           "    Description: %s\n"
-           "    Sample Specification: %s\n"
-           "    Channel Map: %s\n"
-           "    Owner Module: %u\n"
-           "    Volume: %s\n"
-           "    Monitor if Sink: %u\n"
-           "    Latency: %0.0f usec\n"
-           "    Flags: %s%s%s\n",
-           i->index,
-           i->name,
-           i->driver,
-           i->description,
-           pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),
-           pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
-           i->owner_module,
-           i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume),
-           i->monitor_of_sink,
-           (double) i->latency,
-           i->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
-           i->flags & PA_SOURCE_LATENCY ? "LATENCY " : "",
-           i->flags & PA_SOURCE_HARDWARE ? "HARDWARE" : "");
-
-    if (not context->inSourceList(i->name))
-        context->sourceList_.push_back(i->name);
+          "    Name: %s\n"
+          "    Driver: %s\n"
+          "    Description: %s\n"
+          "    Sample Specification: %s\n"
+          "    Channel Map: %s\n"
+          "    Owner Module: %u\n"
+          "    Volume: %s\n"
+          "    Monitor if Sink: %u\n"
+          "    Latency: %0.0f usec\n"
+          "    Flags: %s%s%s\n",
+          i->index,
+          i->name,
+          i->driver,
+          i->description,
+          pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),
+          pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
+          i->owner_module,
+          i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume),
+          i->monitor_of_sink,
+          (double) i->latency,
+          i->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
+          i->flags & PA_SOURCE_LATENCY ? "LATENCY " : "",
+          i->flags & PA_SOURCE_HARDWARE ? "HARDWARE" : "");
+
+    if (not context->inSourceList(i->name)) {
+        PaDeviceInfos ep_infos(i->index, i->name, i->sample_spec, i->channel_map);
+        context->sourceList_.push_back(ep_infos);
+    }
 }
 
 void PulseLayer::sink_input_info_callback(pa_context *c UNUSED, const pa_sink_info *i, int eol, void *userdata)
@@ -625,26 +721,32 @@ void PulseLayer::sink_input_info_callback(pa_context *c UNUSED, const pa_sink_in
           i->flags & PA_SINK_LATENCY ? "LATENCY " : "",
           i->flags & PA_SINK_HARDWARE ? "HARDWARE" : "");
 
-    if (not context->inSinkList(i->name))
-        context->sinkList_.push_back(i->name);
+    if (not context->inSinkList(i->name)) {
+        PaDeviceInfos ep_infos(i->index, i->name, i->sample_spec, i->channel_map);
+        context->sinkList_.push_back(ep_infos);
+    }
 }
 
 void PulseLayer::updatePreference(AudioPreference &preference, int index, PCMType type)
 {
     const std::string devName(getAudioDeviceName(index, type));
+
     switch (type) {
         case SFL_PCM_PLAYBACK:
             DEBUG("setting %s for playback", devName.c_str());
             preference.setPulseDevicePlayback(devName);
             break;
+
         case SFL_PCM_CAPTURE:
             DEBUG("setting %s for capture", devName.c_str());
             preference.setPulseDeviceRecord(devName);
             break;
+
         case SFL_PCM_RINGTONE:
             DEBUG("setting %s for ringer", devName.c_str());
             preference.setPulseDeviceRingtone(devName);
             break;
+
         default:
             break;
     }
diff --git a/daemon/src/audio/pulseaudio/pulselayer.h b/daemon/src/audio/pulseaudio/pulselayer.h
index ddba192f3759cd93178395b3010b2a9fc976783f..cb6fa6e481a17f17f466ec54aac39bb7c598a512 100644
--- a/daemon/src/audio/pulseaudio/pulselayer.h
+++ b/daemon/src/audio/pulseaudio/pulselayer.h
@@ -3,6 +3,7 @@
  *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
  *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
  *  Author: Андрей Лухнов <aol.nnov@gmail.com>
+ *  Author: Adrien Beraud <adrien.beraud@gmail.com>
  *
  *  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
@@ -39,10 +40,38 @@
 #include <pulse/stream.h>
 #include "audio/audiolayer.h"
 #include "noncopyable.h"
+#include "logger.h"
 
 class AudioPreference;
 class AudioStream;
 
+/**
+ * Convenience structure to hold PulseAudio device propreties such as supported channel number etc.
+ */
+typedef struct PaDeviceInfos {
+        uint32_t index;
+        std::string name;
+        pa_sample_spec sample_spec;
+        pa_channel_map channel_map;
+
+        PaDeviceInfos(unsigned idx, const char* ep_name, const pa_sample_spec &samp_spec, const pa_channel_map &chan_map)
+            : index(idx), name(ep_name), sample_spec(samp_spec), channel_map(chan_map) {}
+        virtual ~PaDeviceInfos() {}
+
+        /**
+         * Unary function to search for a device by name in a list using std functions.
+         */
+        class nameComparator {
+            public:
+                explicit nameComparator(const std::string &ref) : baseline(ref) {}
+                bool operator()(const PaDeviceInfos &arg) {
+                    return arg.name == baseline;
+                }
+            private:
+                const std::string &baseline;
+        };
+} PaDeviceInfos;
+
 class PulseLayer : public AudioLayer {
     public:
         PulseLayer(AudioPreference &pref);
@@ -60,13 +89,14 @@ class PulseLayer : public AudioLayer {
 
         void updateSourceList();
 
-        bool inSinkList(const std::string &deviceName) const;
+        bool inSinkList(const std::string &deviceName);
 
-        bool inSourceList(const std::string &deviceName) const;
+        bool inSourceList(const std::string &deviceName);
 
         virtual std::vector<std::string> getCaptureDeviceList() const;
         virtual std::vector<std::string> getPlaybackDeviceList() const;
         int getAudioDeviceIndex(const std::string& name) const;
+
         std::string getAudioDeviceName(int index, PCMType type) const;
 
         virtual void startStream();
@@ -122,18 +152,22 @@ class PulseLayer : public AudioLayer {
         /**
          * Contain the list of playback devices
          */
-        std::vector<std::string> sinkList_;
+        std::vector<PaDeviceInfos> sinkList_;
 
         /**
          * Contain the list of capture devices
          */
-        std::vector<std::string> sourceList_;
+        std::vector<PaDeviceInfos> sourceList_;
+
+        /**
+         * Returns a pointer to the PaEndpointInfos with the given name in sourceList_, or NULL if not found.
+         */
+        const PaDeviceInfos* getDeviceInfos(const std::vector<PaDeviceInfos>&, const std::string& name) const;
 
         /*
          * Buffers used to avoid doing malloc/free in the audio thread
          */
-        SFLDataFormat *mic_buffer_;
-        size_t mic_buf_size_;
+        AudioBuffer mic_buffer_;
 
         /** PulseAudio context and asynchronous loop */
         pa_context* context_;
diff --git a/daemon/src/audio/recordable.cpp b/daemon/src/audio/recordable.cpp
index ebf30ee24da732c4dabf7030a679ab23a272f1d5..4696c8de4fb11756e4e2b70a175372ba0d50d727 100644
--- a/daemon/src/audio/recordable.cpp
+++ b/daemon/src/audio/recordable.cpp
@@ -31,10 +31,10 @@
 #include "manager.h"
 #include "logger.h"
 
-Recordable::Recordable() : recAudio_(), recorder_(&recAudio_, &Manager::instance().getMainBuffer())
+Recordable::Recordable() : recAudio_(), recorder_(&recAudio_, Manager::instance().getMainBuffer())
 {
     DEBUG("Set recording options: %s", Manager::instance().audioPreference.getRecordPath().c_str());
-    recAudio_.setRecordingOption(AudioRecord::FILE_WAV, 8000, Manager::instance().audioPreference.getRecordPath());
+    recAudio_.setRecordingOptions(8000, Manager::instance().audioPreference.getRecordPath());
 }
 
 Recordable::~Recordable()
diff --git a/daemon/src/audio/ringbuffer.cpp b/daemon/src/audio/ringbuffer.cpp
index a37e3ecce67a9e93ec21f5bc20d723b55ce19b7a..e054affba4785ff61ded42995750dffe0fabaee0 100644
--- a/daemon/src/audio/ringbuffer.cpp
+++ b/daemon/src/audio/ringbuffer.cpp
@@ -3,6 +3,7 @@
  *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
  *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
  *  Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
+ *  Author: Adrien Beraud <adrien.beraud@gmail.com>
  *
  *  Portions (c) Dominic Mazzoni (Audacity)
  *
@@ -40,18 +41,18 @@
 #include "ringbuffer.h"
 
 namespace {
-    // corresponds to 106 ms (about 5 rtp packets)
-    const size_t MIN_BUFFER_SIZE = 1280;
+// corresponds to 160 ms (about 5 rtp packets)
+const size_t MIN_BUFFER_SIZE = 1280;
 }
 
 // Create  a ring buffer with 'size' bytes
 RingBuffer::RingBuffer(size_t size, const std::string &call_id) :
-      endPos_(0)
-    , bufferSize_(size > MIN_BUFFER_SIZE ? size : MIN_BUFFER_SIZE)
-    , buffer_(bufferSize_)
+    endPos_(0)
+    , buffer_(std::max(size, MIN_BUFFER_SIZE), 1)
     , readpointers_()
     , buffer_id_(call_id)
-{}
+{
+}
 
 void
 RingBuffer::flush(const std::string &call_id)
@@ -72,19 +73,21 @@ RingBuffer::flushAll()
 size_t
 RingBuffer::putLength() const
 {
+    const size_t buffer_size = buffer_.samples();
     const size_t startPos = (not readpointers_.empty()) ? getSmallestReadPointer() : 0;
-    return (endPos_ + bufferSize_ - startPos) % bufferSize_;
+    return (endPos_ + buffer_size - startPos) % buffer_size;
 }
 
 size_t RingBuffer::getLength(const std::string &call_id) const
 {
-    return (endPos_ + bufferSize_ - getReadPointer(call_id)) % bufferSize_;
+    const size_t buffer_size = buffer_.samples();
+    return (endPos_ + buffer_size - getReadPointer(call_id)) % buffer_size;
 }
 
 void
 RingBuffer::debug()
 {
-    DEBUG("Start=%d; End=%d; BufferSize=%d", getSmallestReadPointer(), endPos_, bufferSize_);
+    DEBUG("Start=%d; End=%d; BufferSize=%d", getSmallestReadPointer(), endPos_, buffer_.samples());
 }
 
 size_t RingBuffer::getReadPointer(const std::string &call_id) const
@@ -102,7 +105,7 @@ RingBuffer::getSmallestReadPointer() const
     if (hasNoReadPointers())
         return 0;
 
-    size_t smallest = bufferSize_;
+    size_t smallest = buffer_.samples();
 
     ReadPointer::const_iterator iter;
 
@@ -160,29 +163,35 @@ bool RingBuffer::hasNoReadPointers() const
 //
 
 // This one puts some data inside the ring buffer.
-void
-RingBuffer::put(void* buffer, size_t toCopy)
+void RingBuffer::put(AudioBuffer& buf)
 {
     const size_t len = putLength();
+    const size_t sample_num = buf.samples();
+    const size_t buffer_size = buffer_.samples();
+    size_t toCopy = sample_num;
 
-    if (toCopy > bufferSize_ - len)
-        toCopy = bufferSize_ - len;
+    // Add more channels if the input buffer holds more channels than the ring.
+    if (buffer_.channels() < buf.channels())
+        buffer_.setChannelNum(buf.channels());
 
-    unsigned char *src = static_cast<unsigned char *>(buffer);
+    if (toCopy > buffer_size - len)
+        toCopy = buffer_size - len;
 
+    size_t in_pos = 0;
     size_t pos = endPos_;
 
     while (toCopy) {
         size_t block = toCopy;
 
-        if (block > bufferSize_ - pos) // Wrap block around ring ?
-            block = bufferSize_ - pos; // Fill in to the end of the buffer
+        if (block > buffer_size - pos) // Wrap block around ring ?
+            block = buffer_size - pos; // Fill in to the end of the buffer
 
-        memcpy(&(*buffer_.begin()) + pos, src, block);
-        src += block;
-        pos = (pos + block) % bufferSize_;
+        buffer_.copy(buf, block, in_pos, pos);
+        in_pos += block;
+        pos = (pos + block) % buffer_size;
         toCopy -= block;
     }
+
     endPos_ = pos;
 }
 
@@ -198,8 +207,7 @@ RingBuffer::availableForGet(const std::string &call_id) const
 }
 
 // Get will move 'toCopy' bytes from the internal FIFO to 'buffer'
-size_t
-RingBuffer::get(void *buffer, size_t toCopy, const std::string &call_id)
+size_t RingBuffer::get(AudioBuffer& buf, const std::string &call_id)
 {
     if (hasNoReadPointers())
         return 0;
@@ -208,24 +216,25 @@ RingBuffer::get(void *buffer, size_t toCopy, const std::string &call_id)
         return 0;
 
     const size_t len = getLength(call_id);
-
-    if (toCopy > len)
-        toCopy = len;
+    const size_t sample_num = buf.samples();
+    const size_t buffer_size = buffer_.samples();
+    size_t toCopy = std::min(sample_num, len);
 
     const size_t copied = toCopy;
 
-    unsigned char *dest = (unsigned char *) buffer;
+    size_t dest = 0;
     size_t startPos = getReadPointer(call_id);
 
     while (toCopy > 0) {
         size_t block = toCopy;
 
-        if (block > bufferSize_ - startPos)
-            block = bufferSize_ - startPos;
+        if (block > buffer_size - startPos)
+            block = buffer_size - startPos;
+
+        buf.copy(buffer_, block, startPos, dest);
 
-        memcpy(dest, &(*buffer_.begin()) + startPos, block);
         dest += block;
-        startPos = (startPos + block) % bufferSize_;
+        startPos = (startPos + block) % buffer_size;
         toCopy -= block;
     }
 
@@ -241,7 +250,8 @@ RingBuffer::discard(size_t toDiscard, const std::string &call_id)
     if (toDiscard > len)
         toDiscard = len;
 
-    size_t startPos = (getReadPointer(call_id) + toDiscard) % bufferSize_;
+    size_t buffer_size = buffer_.samples();
+    size_t startPos = (getReadPointer(call_id) + toDiscard) % buffer_size;
 
     storeReadPointer(startPos, call_id);
 
diff --git a/daemon/src/audio/ringbuffer.h b/daemon/src/audio/ringbuffer.h
index b4c4b3a4922bd459a3496e321b461afc7a571241..9977e8978508ff1ea0a0444aa34bcbf287b54d27 100644
--- a/daemon/src/audio/ringbuffer.h
+++ b/daemon/src/audio/ringbuffer.h
@@ -3,6 +3,7 @@
  *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
  *  Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
  *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *  Author: Adrien Beraud <adrien.beraud@gmail.com>
  *
  *  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
@@ -25,10 +26,15 @@
 #include <fstream>
 #include <vector>
 #include <map>
+
 #include "noncopyable.h"
+#include "audiobuffer.h"
 
 typedef std::map<std::string, size_t> ReadPointer;
 
+/**
+ * A ring buffer for mutichannel audio samples
+ */
 class RingBuffer {
     public:
         /**
@@ -92,11 +98,11 @@ class RingBuffer {
          * @param buffer Data to copied
          * @param toCopy Number of bytes to copy
          */
-        void put(void* buffer, size_t toCopy);
+         void put(AudioBuffer& buf);
 
         /**
-         * To get how much space is available in the buffer to read in
-         * @return int The available size
+         * To get how much samples are available in the buffer to read in
+         * @return int The available (multichannel) samples number
          */
         size_t availableForGet(const std::string &call_id) const;
 
@@ -106,12 +112,12 @@ class RingBuffer {
          * @param toCopy Number of bytes to copy
          * @return size_t Number of bytes copied
          */
-        size_t get(void* buffer, size_t toCopy, const std::string &call_id);
+         size_t get(AudioBuffer& buf, const std::string &call_id);
 
         /**
          * Discard data from the buffer
-         * @param toDiscard Number of bytes to discard
-         * @return size_t Number of bytes discarded
+         * @param toDiscard Number of samples to discard
+         * @return size_t Number of samples discarded
          */
         size_t discard(size_t toDiscard, const std::string &call_id);
 
@@ -129,14 +135,13 @@ class RingBuffer {
         void debug();
 
     private:
+        /* POULET! */
         NON_COPYABLE(RingBuffer);
 
         /** Pointer on the last data */
         size_t endPos_;
-        /** Buffer size */
-        size_t bufferSize_;
         /** Data */
-        std::vector<unsigned char> buffer_;
+        AudioBuffer buffer_;
 
         ReadPointer readpointers_;
         std::string buffer_id_;
diff --git a/daemon/src/audio/samplerateconverter.cpp b/daemon/src/audio/samplerateconverter.cpp
index 8397f1a9e79381888ca68b2df3cf59d6e2634fb9..337e0df4f654b4c88b87bbeebcc57931434c22e4 100644
--- a/daemon/src/audio/samplerateconverter.cpp
+++ b/daemon/src/audio/samplerateconverter.cpp
@@ -29,76 +29,81 @@
  */
 
 #include "samplerateconverter.h"
-#include "manager.h"
-#include <cassert>
-#include "logger.h"
+#include "sfl_types.h"
 
-SamplerateConverter::SamplerateConverter(int freq) : floatBufferIn_(0),
-    floatBufferOut_(0), samples_(0), maxFreq_(freq), src_state_(0)
+SamplerateConverter::SamplerateConverter(int freq, size_t channels /* = 1 */) : floatBufferIn_(),
+    floatBufferOut_(), samples_(0), channels_(channels), maxFreq_(freq), src_state_(0)
 {
     int err;
-    src_state_ = src_new(SRC_LINEAR, 1, &err);
+    src_state_ = src_new(SRC_LINEAR, channels_, &err);
 
     samples_ = (freq * 20) / 1000; // start with 20 ms buffers
 
-    floatBufferIn_ = new float[samples_];
-    floatBufferOut_ = new float[samples_];
+    floatBufferIn_.resize(samples_);
+    floatBufferOut_.resize(samples_);
 }
 
 SamplerateConverter::~SamplerateConverter()
 {
-    delete [] floatBufferIn_;
-    delete [] floatBufferOut_;
-
     src_delete(src_state_);
 }
 
 void
-SamplerateConverter::Short2FloatArray(const short *in, float *out, int len)
+SamplerateConverter::Short2FloatArray(const SFLAudioSample *in, float *out, int len)
 {
     // factor is 1/(2^15), used to rescale the short int range to the
     // [-1.0 - 1.0] float range.
+    static const float FACTOR = 1.0f / (1 << 15);
 
     while (len--)
-        out[len] = (float) in[len] * .000030517578125f;
+        out[len] = (float) in[len] * FACTOR;
 }
 
-void SamplerateConverter::resample(SFLDataFormat *dataIn,
-                                   SFLDataFormat *dataOut,
-                                   size_t dataOutSize, int inputFreq,
-                                   int outputFreq, size_t nbSamples)
+void SamplerateConverter::resample(const AudioBuffer &dataIn, AudioBuffer &dataOut)
 {
-    double sampleFactor = (double) outputFreq / inputFreq;
+    const double inputFreq = dataIn.getSampleRate();
+    const double outputFreq = dataOut.getSampleRate();
+    const double sampleFactor = outputFreq / inputFreq;
 
     if (sampleFactor == 1.0)
         return;
 
-    size_t outSamples = nbSamples * sampleFactor;
-    const unsigned int maxSamples = std::max(outSamples, nbSamples);
+    const size_t nbFrames = dataIn.samples();
+    const size_t nbChans = dataIn.channels();
 
-    if (maxSamples > samples_) {
-        /* grow buffer if needed */
-        samples_ = maxSamples;
-        delete [] floatBufferIn_;
-        delete [] floatBufferOut_;
-        floatBufferIn_ = new float[samples_];
-        floatBufferOut_ = new float[samples_];
+    if (nbChans != channels_) {
+        // change channel num if needed
+        int err;
+        src_delete(src_state_);
+        src_state_ = src_new(SRC_LINEAR, nbChans, &err);
+        channels_ = nbChans;
     }
 
+    size_t inSamples = nbChans * nbFrames;
+    size_t outSamples = inSamples * sampleFactor;
+
+    // grow buffer if needed
+    samples_ = std::max(inSamples, outSamples);
+    floatBufferIn_.resize(inSamples);
+    floatBufferOut_.resize(outSamples);
+
     SRC_DATA src_data;
-    src_data.data_in = floatBufferIn_;
-    src_data.data_out = floatBufferOut_;
-    src_data.input_frames = nbSamples;
-    src_data.output_frames = outSamples;
+    src_data.data_in = floatBufferIn_.data();
+    src_data.data_out = floatBufferOut_.data();
+    src_data.input_frames = nbFrames;
+    src_data.output_frames = nbFrames * sampleFactor;
     src_data.src_ratio = sampleFactor;
     src_data.end_of_input = 0; // More data will come
 
-    Short2FloatArray(dataIn, floatBufferIn_, nbSamples);
+    dataIn.interleaveFloat(floatBufferIn_.data());
+
     src_process(src_state_, &src_data);
 
-    if (outSamples > dataOutSize) {
-        ERROR("Outsamples exceeds output buffer size, clamping to %u", dataOutSize);
-        outSamples = dataOutSize;
-    }
-    src_float_to_short_array(floatBufferOut_, dataOut, outSamples);
+    /*
+    TODO: one-shot deinterleave and float-to-short conversion
+    currently using floatBufferIn_ as scratch
+    */
+    SFLAudioSample *scratch_buff = reinterpret_cast<SFLAudioSample *>(floatBufferIn_.data());
+    src_float_to_short_array(floatBufferOut_.data(), scratch_buff, outSamples);
+    dataOut.deinterleave(scratch_buff, src_data.output_frames, nbChans);
 }
diff --git a/daemon/src/audio/samplerateconverter.h b/daemon/src/audio/samplerateconverter.h
index bb2c52aacb67a58ae7f2aa6d0e5c6ec800000596..2b533e208347e6359eaf78a511532118659b30e2 100644
--- a/daemon/src/audio/samplerateconverter.h
+++ b/daemon/src/audio/samplerateconverter.h
@@ -35,6 +35,7 @@
 #include <cmath>
 #include <cstring>
 
+#include "audiobuffer.h"
 #include "sfl_types.h"
 #include "noncopyable.h"
 
@@ -47,7 +48,7 @@ class SamplerateConverter {
         * internal buffer size. Converter must be reinitialized
         * every time these parameters change
         */
-        SamplerateConverter(int freq);
+        SamplerateConverter(int freq, size_t channels = 1);
 
         /** Destructor */
         ~SamplerateConverter();
@@ -59,7 +60,8 @@ class SamplerateConverter {
          * @param SamplerateConverter2 The desired sample rate
          * @param nbSamples	  The number of samples to process
          */
-        void resample(SFLDataFormat* dataIn, SFLDataFormat* dataOut, size_t dataOutSize, int oldrate, int newrate, size_t nbSamples);
+        //void resample(SFLAudioSample* dataIn, SFLAudioSample* dataOut, size_t dataOutSize, int oldrate, int newrate, size_t nbSamples);
+        void resample(const AudioBuffer& dataIn, AudioBuffer& dataOut);
 
         /**
          * Convert short table to floats for audio processing
@@ -67,16 +69,18 @@ class SamplerateConverter {
          * @param out The resulting (float) array
          * @param len The number of elements in both tables
          */
-        void Short2FloatArray(const short *in, float *out, int len);
+        void Short2FloatArray(const SFLAudioSample *in, float *out, int len);
 
 
     private:
         NON_COPYABLE(SamplerateConverter);
 
         /* temporary buffers */
-        float * floatBufferIn_;
-        float * floatBufferOut_;
+        std::vector<float> floatBufferIn_;
+        std::vector<float> floatBufferOut_;
+
         size_t samples_; // size in samples of temporary buffers
+        size_t channels_; // number of channels configured
         int maxFreq_; // maximal output frequency
 
         SRC_STATE* src_state_;
diff --git a/daemon/src/audio/sound/audiofile.cpp b/daemon/src/audio/sound/audiofile.cpp
index 227f1bad04dd02040bd0586e6b28c6dea7be64c2..3cfedd333e582e1dbfe5451b2ae916d432bf1be8 100644
--- a/daemon/src/audio/sound/audiofile.cpp
+++ b/daemon/src/audio/sound/audiofile.cpp
@@ -36,178 +36,99 @@
 #include <cstring>
 #include <vector>
 #include <climits>
+#include <sndfile.hh>
 
 #include "audiofile.h"
-#include "audio/codecs/audiocodec.h"
 #include "audio/samplerateconverter.h"
+#include "client/callmanager.h"
+#include "manager.h"
+
 #include "logger.h"
 
-RawFile::RawFile(const std::string& name, sfl::AudioCodec *codec, unsigned int sampleRate)
-    : AudioFile(name, sampleRate), audioCodec_(codec)
+void
+AudioFile::onBufferFinish()
 {
-    if (filepath_.empty())
-        throw AudioFileException("Unable to open audio file: filename is empty");
-
-    std::fstream file;
-    file.open(filepath_.c_str(), std::fstream::in);
-
-    if (!file.is_open())
-        throw AudioFileException("Unable to open audio file");
-
-    file.seekg(0, std::ios::end);
-    size_t length = file.tellg();
-    file.seekg(0, std::ios::beg);
-
-    std::vector<char> fileBuffer(length);
-    file.read(&fileBuffer[0], length);
-    file.close();
-
-    const unsigned int frameSize = audioCodec_->getFrameSize();
-    const unsigned int bitrate   = audioCodec_->getBitRate() * 1000 / 8;
-    const unsigned int audioRate = audioCodec_->getClockRate();
-    const unsigned int encFrameSize = frameSize * bitrate / audioRate;
-    const unsigned int decodedSize = length * (frameSize / encFrameSize);
-
-    SFLDataFormat *monoBuffer = new SFLDataFormat[decodedSize];
-    SFLDataFormat *bufpos = monoBuffer;
-    unsigned char *filepos = reinterpret_cast<unsigned char *>(&fileBuffer[0]);
-    size_ = decodedSize;
-
-    while (length >= encFrameSize) {
-        bufpos += audioCodec_->decode(bufpos, filepos, encFrameSize);
-        filepos += encFrameSize;
-        length -= encFrameSize;
+    // We want to send values in milisecond
+    const int divisor = buffer_->getSampleRate() / 1000;
+
+    if (divisor == 0) {
+        ERROR("Error cannot update playback slider, sampling rate is 0");
+        return;
     }
 
-    if (sampleRate == audioRate)
-        buffer_ = monoBuffer;
-    else {
-        double factord = (double) sampleRate / audioRate;
-        float* floatBufferIn = new float[size_];
-        int    sizeOut  = ceil(factord * size_);
-        src_short_to_float_array(monoBuffer, floatBufferIn, size_);
-        delete [] monoBuffer;
-        delete [] buffer_;
-        buffer_ = new SFLDataFormat[sizeOut];
-
-        SRC_DATA src_data;
-        src_data.data_in = floatBufferIn;
-        src_data.input_frames = size_;
-        src_data.output_frames = sizeOut;
-        src_data.src_ratio = factord;
-
-        float* floatBufferOut = new float[sizeOut];
-        src_data.data_out = floatBufferOut;
-
-        src_simple(&src_data, SRC_SINC_BEST_QUALITY, 1);
-        src_float_to_short_array(floatBufferOut, buffer_, src_data.output_frames_gen);
-
-        delete [] floatBufferOut;
-        delete [] floatBufferIn;
-        size_ = src_data.output_frames_gen;
+    if ((updatePlaybackScale_ % 5) == 0) {
+        CallManager *cm = Manager::instance().getClient()->getCallManager();
+        cm->updatePlaybackScale(filepath_, pos_ / divisor, buffer_->samples() / divisor);
     }
-}
 
+    updatePlaybackScale_++;
+}
 
-WaveFile::WaveFile(const std::string &fileName, unsigned int sampleRate) : AudioFile(fileName, sampleRate)
+AudioFile::AudioFile(const std::string &fileName, unsigned int sampleRate) :
+    AudioLoop(sampleRate), filepath_(fileName), updatePlaybackScale_(0)
 {
-    const std::fstream fs(fileName.c_str(), std::ios_base::in);
-
-    if (!fs)
-        throw AudioFileException("File " + fileName + " doesn't exist");
-
-    std::fstream fileStream;
-    fileStream.open(fileName.c_str(), std::ios::in | std::ios::binary);
-
-    char riff[4] = { 0, 0, 0, 0 };
-    fileStream.read(riff, sizeof riff / sizeof *riff);
-
-    if (strncmp("RIFF", riff, sizeof riff / sizeof *riff) != 0)
-        throw AudioFileException("File is not of RIFF format");
-
-    char fmt[4] = { 0, 0, 0, 0 };
-    int maxIteration = 10;
-
-    while (maxIteration-- and strncmp("fmt ", fmt, sizeof fmt / sizeof *fmt))
-        fileStream.read(fmt, sizeof fmt / sizeof *fmt);
-
-    if (maxIteration == 0)
-        throw AudioFileException("Could not find \"fmt \" chunk");
-
-    SINT32 chunkSize; // fmt chunk size
-    fileStream.read(reinterpret_cast<char *>(&chunkSize), sizeof chunkSize); // Read fmt chunk size.
-    unsigned short formatTag; // data compression tag
-    fileStream.read(reinterpret_cast<char *>(&formatTag), sizeof formatTag);
-
-    if (formatTag != 1) // PCM = 1, FLOAT = 3
-        throw AudioFileException("File contains an unsupported data format type");
-
-    // Get number of channels from the header.
-    SINT16 chan;
-    fileStream.read(reinterpret_cast<char *>(&chan), sizeof chan);
-
-    if (chan > 2)
-        throw AudioFileException("WaveFile: unsupported number of channels");
-
-    // Get file sample rate from the header.
-    SINT32 fileRate;
-    fileStream.read(reinterpret_cast<char *>(&fileRate), sizeof fileRate);
-
-    SINT32 avgb;
-    fileStream.read(reinterpret_cast<char *>(&avgb), sizeof avgb);
-
-    SINT16 blockal;
-    fileStream.read(reinterpret_cast<char *>(&blockal), sizeof blockal);
+    int format;
+    bool hasHeader = true;
+
+    if (filepath_.find(".wav") != std::string::npos) {
+        format = SF_FORMAT_WAV;
+    } else if (filepath_.find(".ul") != std::string::npos) {
+        format = SF_FORMAT_RAW | SF_FORMAT_ULAW;
+        hasHeader = false;
+    } else if (filepath_.find(".al") != std::string::npos) {
+        format = SF_FORMAT_RAW | SF_FORMAT_ALAW;
+        hasHeader = false;
+    } else if (filepath_.find(".au") != std::string::npos) {
+        format = SF_FORMAT_AU;
+    } else if (filepath_.find(".flac") != std::string::npos) {
+        format = SF_FORMAT_FLAC;
+    } else if (filepath_.find(".ogg") != std::string::npos) {
+        format = SF_FORMAT_OGG;
+    } else {
+        WARN("No file extension, guessing WAV");
+        format = SF_FORMAT_WAV;
+    }
 
-    // Determine the data type
-    SINT16 dt;
-    fileStream.read(reinterpret_cast<char *>(&dt), sizeof dt);
+    SndfileHandle fileHandle(fileName.c_str(), SFM_READ, format, hasHeader ? 0 : 1,
+                             hasHeader ? 0 : 8000);
 
-    if (dt != 8 && dt != 16 && dt != 32)
-        throw AudioFileException("File's bits per sample with is not supported");
+    if (!fileHandle)
+        throw AudioFileException("File " + fileName + " doesn't exist");
 
-    // Find the "data" chunk
-    char data[4] = { 0, 0, 0, 0 };
-    maxIteration = 10;
+    switch (fileHandle.channels()) {
+        case 1:
+        case 2:
+            break;
+        default:
+            throw AudioFileException("Unsupported number of channels");
+    }
 
-    while (maxIteration-- && strncmp("data", data, sizeof data / sizeof *data))
-        fileStream.read(data, sizeof data / sizeof *data);
+    // get # of bytes in file
+    const size_t fileSize = fileHandle.seek(0, SEEK_END);
+    fileHandle.seek(0, SEEK_SET);
 
-    // Samplerate converter initialized with 88200 sample long
-    const int rate = static_cast<SINT32>(sampleRate_);
-    SamplerateConverter converter(std::max(fileRate, rate));
+    const sf_count_t nbFrames = hasHeader ? fileHandle.frames() : fileSize / fileHandle.channels();
 
-    // Get length of data from the header.
-    SINT32 bytes;
-    fileStream.read(reinterpret_cast<char *>(&bytes), sizeof bytes);
-    
-    // sample frames, should not be longer than a minute
-    int nbSamples = std::min(60 * fileRate, 8 * bytes / dt / chan);
+    SFLAudioSample * interleaved = new SFLAudioSample[nbFrames * fileHandle.channels()];
 
-    DEBUG("Frame size %ld, data size %d align %d rate %d avgbyte %d "
-          "chunk size %d dt %d", nbSamples, bytes, blockal, fileRate, avgb,
-          chunkSize, dt);
+    // get n "items", aka samples (not frames)
+    fileHandle.read(interleaved, nbFrames * fileHandle.channels());
 
-    size_ = nbSamples;
-    SFLDataFormat *tempBuffer = new SFLDataFormat[size_];
+    AudioBuffer * buffer = new AudioBuffer(nbFrames, fileHandle.channels(), fileHandle.samplerate());
+    buffer->deinterleave(interleaved, nbFrames, fileHandle.channels());
+    delete [] interleaved;
 
-    fileStream.read(reinterpret_cast<char *>(tempBuffer),
-                    nbSamples * sizeof(SFLDataFormat));
+    const int rate = static_cast<int32_t>(sampleRate);
 
-    // mix two channels together if stereo
-    if (chan == 2) {
-        for (int i = 0, j = 0; i < nbSamples - 1; i += 2, ++j)
-            tempBuffer[j] = (tempBuffer[i] + tempBuffer[i + 1]) * 0.5;
-        nbSamples *= 0.5;
+    if (fileHandle.samplerate() != rate) {
+        SamplerateConverter converter(std::max(fileHandle.samplerate(), rate), fileHandle.channels());
+        AudioBuffer * resampled = new AudioBuffer(nbFrames, fileHandle.channels(), rate);
+        converter.resample(*buffer, *resampled);
+        delete buffer;
+        delete buffer_;
+        buffer_ = resampled;
+    } else {
+        delete buffer_;
+        buffer_ = buffer;
     }
-
-    if (fileRate != rate) {
-        const float ratio = sampleRate_ / (float) fileRate;
-        const int outSamples = ceil(nbSamples * ratio);
-        size_ = outSamples;
-        buffer_ = new SFLDataFormat[size_];
-        converter.resample(tempBuffer, buffer_, size_, fileRate, sampleRate_, nbSamples);
-        delete [] tempBuffer;
-    } else
-        buffer_ = tempBuffer;
 }
diff --git a/daemon/src/audio/sound/audiofile.h b/daemon/src/audio/sound/audiofile.h
index 621e038a67b441c0cd65aab4e45c59f0ba0b43ba..ff3530b5e34de57559ca2b87e2d7a84d14741a03 100644
--- a/daemon/src/audio/sound/audiofile.h
+++ b/daemon/src/audio/sound/audiofile.h
@@ -37,10 +37,6 @@
 #include <stdexcept>
 #include "audio/audioloop.h"
 
-namespace sfl {
-class AudioCodec;
-}
-
 class AudioFileException : public std::runtime_error {
     public:
         AudioFileException(const std::string &str) :
@@ -52,8 +48,7 @@ class AudioFileException : public std::runtime_error {
  */
 class AudioFile : public AudioLoop {
     public:
-        AudioFile(const std::string &filepath, unsigned int sampleRate) : AudioLoop(sampleRate), filepath_(filepath)
-        {}
+        AudioFile(const std::string &filepath, unsigned int sampleRate);
 
         std::string getFilePath() const {
             return filepath_;
@@ -62,30 +57,11 @@ class AudioFile : public AudioLoop {
     protected:
         /** The absolute path to the sound file */
         std::string filepath_;
-};
-
-class RawFile : public AudioFile {
-    public:
-        /**
-         * Constructor
-         */
-        RawFile(const std::string& name, sfl::AudioCodec* codec, unsigned int sampleRate = 8000);
 
     private:
-        NON_COPYABLE(RawFile);
-
-        /** Your preferred codec */
-        sfl::AudioCodec* audioCodec_;
-};
-
-class WaveFile : public AudioFile {
-    public:
-        /**
-         * Load a sound file in memory
-         * @param filename      The absolute path to the file
-         * @param sampleRate    The sample rate to read it
-         */
-        WaveFile(const std::string&, unsigned int sampleRate);
+        // override
+        void onBufferFinish();
+        unsigned updatePlaybackScale_;
 };
 
 #endif // __AUDIOFILE_H__
diff --git a/daemon/src/audio/sound/dtmf.cpp b/daemon/src/audio/sound/dtmf.cpp
index afddf9beac09825bd883d6be782508045bc56e8c..5a70553909c8c521ac218a43b333127991f72436 100644
--- a/daemon/src/audio/sound/dtmf.cpp
+++ b/daemon/src/audio/sound/dtmf.cpp
@@ -45,7 +45,7 @@ void DTMF::startTone(char code)
 
 using std::vector;
 
-bool DTMF::generateDTMF(vector<SFLDataFormat> &buffer)
+bool DTMF::generateDTMF(vector<SFLAudioSample> &buffer)
 {
     try {
         if (currentTone_ != 0) {
@@ -71,8 +71,7 @@ bool DTMF::generateDTMF(vector<SFLDataFormat> &buffer)
                 dtmfgenerator_.getSamples(buffer, newTone_);
                 currentTone_ = newTone_;
                 return true;
-            }
-            else
+            } else
                 return false;
         }
     } catch (const DTMFException &e) {
diff --git a/daemon/src/audio/sound/dtmf.h b/daemon/src/audio/sound/dtmf.h
index 7b1ebc5d4659146f7c05a5df7ace297144f01897..f53c36671bf3dcbd68a140443dd20593e0047a7d 100644
--- a/daemon/src/audio/sound/dtmf.h
+++ b/daemon/src/audio/sound/dtmf.h
@@ -58,9 +58,9 @@ class DTMF {
 
         /**
          * Copy the sound inside the sampling* buffer
-         * @param buffer : a vector of SFLDataFormat
+         * @param buffer : a vector of SFLAudioSample
          */
-        bool generateDTMF(std::vector<SFLDataFormat> &buffer);
+        bool generateDTMF(std::vector<SFLAudioSample> &buffer);
 
     private:
         char currentTone_;
diff --git a/daemon/src/audio/sound/dtmfgenerator.cpp b/daemon/src/audio/sound/dtmfgenerator.cpp
index ecf986d8a3c88cd1814402791f72aa128b668f5f..d7a32aac3e893c8709af3de8fc661d3a80f6f215 100644
--- a/daemon/src/audio/sound/dtmfgenerator.cpp
+++ b/daemon/src/audio/sound/dtmfgenerator.cpp
@@ -85,7 +85,7 @@ using std::vector;
 /*
  * Get n samples of the signal of code code
  */
-void DTMFGenerator::getSamples(vector<SFLDataFormat> &buffer, unsigned char code)
+void DTMFGenerator::getSamples(vector<SFLAudioSample> &buffer, unsigned char code)
 {
     code = toupper(code);
 
@@ -111,6 +111,7 @@ void DTMFGenerator::getSamples(vector<SFLDataFormat> &buffer, unsigned char code
 
     size_t i;
     const size_t n = buffer.size();
+
     for (i = 0; i < n; ++i)
         buffer[i] = state.sample[i % sampleRate_];
 
@@ -121,23 +122,24 @@ void DTMFGenerator::getSamples(vector<SFLDataFormat> &buffer, unsigned char code
  * Get next n samples (continues where previous call to
  * genSample or genNextSamples stopped
  */
-void DTMFGenerator::getNextSamples(vector<SFLDataFormat> &buffer)
+void DTMFGenerator::getNextSamples(vector<SFLAudioSample> &buffer)
 {
     if (state.sample == 0)
         throw DTMFException("DTMF generator not initialized");
 
     size_t i;
     const size_t n = buffer.size();
+
     for (i = 0; i < n; i++)
         buffer[i] = state.sample[(state.offset + i) % sampleRate_];
 
     state.offset = (state.offset + i) % sampleRate_;
 }
 
-SFLDataFormat* DTMFGenerator::fillToneBuffer(int index)
+SFLAudioSample* DTMFGenerator::fillToneBuffer(int index)
 {
     assert(index >= 0 and index < NUM_TONES);
-    SFLDataFormat* ptr = new SFLDataFormat[sampleRate_];
-    tone_.genSin(ptr, tones_[index].higher, tones_[index].lower,  sampleRate_);
+    SFLAudioSample* ptr = new SFLAudioSample[sampleRate_];
+    tone_.genSin(ptr, tones_[index].higher, tones_[index].lower, sampleRate_);
     return ptr;
 }
diff --git a/daemon/src/audio/sound/dtmfgenerator.h b/daemon/src/audio/sound/dtmfgenerator.h
index 742d88607083108d290bf9baa52ceaf7d0234c6a..a9f600d792e76699f8e60a2ee58195e5df29388b 100644
--- a/daemon/src/audio/sound/dtmfgenerator.h
+++ b/daemon/src/audio/sound/dtmfgenerator.h
@@ -69,7 +69,7 @@ class DTMFGenerator {
         /** State of the DTMF generator */
         struct DTMFState {
             unsigned int offset;   /** Offset in the sample currently being played */
-            SFLDataFormat* sample;         /** Currently generated code */
+            SFLAudioSample* sample;         /** Currently generated code */
         };
 
         /** State of the DTMF generator */
@@ -79,7 +79,7 @@ class DTMFGenerator {
         static const DTMFTone tones_[NUM_TONES];
 
         /** Generated samples for each tone */
-        SFLDataFormat* toneBuffers_[NUM_TONES];
+        SFLAudioSample* toneBuffers_[NUM_TONES];
 
         /** Sampling rate of generated dtmf */
         int sampleRate_;
@@ -101,26 +101,26 @@ class DTMFGenerator {
 
         /*
          * Get n samples of the signal of code code
-         * @param buffer a SFLDataFormat vector
+         * @param buffer a SFLAudioSample vector
          * @param code   dtmf code to get sound
          */
-        void getSamples(std::vector<SFLDataFormat> &buffer, unsigned char code);
+        void getSamples(std::vector<SFLAudioSample> &buffer, unsigned char code);
 
         /*
          * Get next n samples (continues where previous call to
          * genSample or genNextSamples stopped
-         * @param buffer a SFLDataFormat vector
+         * @param buffer a SFLAudioSample vector
          */
-        void getNextSamples(std::vector<SFLDataFormat> &buffer);
+        void getNextSamples(std::vector<SFLAudioSample> &buffer);
 
     private:
 
         /**
          * Fill tone buffer for a given index of the array of tones.
          * @param index of the tone in the array tones_
-         * @return SFLDataFormat* The generated data
+         * @return SFLAudioSample* The generated data
          */
-        SFLDataFormat* fillToneBuffer(int index);
+        SFLAudioSample* fillToneBuffer(int index);
 };
 
 #endif // DTMFGENERATOR_H
diff --git a/daemon/src/audio/sound/tone.cpp b/daemon/src/audio/sound/tone.cpp
index 64d793f2d77ebf03faba81323e09e9c614711f87..d8af35c64cabe9a1922bf39ad0880072cbac2d85 100644
--- a/daemon/src/audio/sound/tone.cpp
+++ b/daemon/src/audio/sound/tone.cpp
@@ -47,6 +47,9 @@ Tone::Tone(const std::string& definition, unsigned int sampleRate) :
     AudioLoop(sampleRate), xhigher_(0.0), xlower_(0.0)
 {
     fillWavetable();
+    delete buffer_;
+    buffer_ = new AudioBuffer();
+    buffer_->setSampleRate(sampleRate);
     genBuffer(definition); // allocate memory with definition parameter
 }
 
@@ -56,10 +59,11 @@ Tone::genBuffer(const std::string& definition)
     if (definition.empty())
         return;
 
-    size_ = 0;
+    size_t size = 0;
+    const int sampleRate = buffer_->getSampleRate();
 
-    std::vector<SFLDataFormat> buffer(SIZEBUF); // 1kb
-    SFLDataFormat* bufferPos = &(*buffer.begin());
+    std::vector<SFLAudioSample> buffer(SIZEBUF); // 1kb
+    SFLAudioSample* bufferPos = buffer.data();
 
     // Number of format sections
     std::string::size_type posStart = 0; // position of precedent comma
@@ -80,7 +84,7 @@ Tone::genBuffer(const std::string& definition)
         {
             // Sample string: "350+440" or "350+440/2000,244+655/2000"
             int freq1, freq2, time;
-            s = definition.substr(posStart, posEnd-posStart);
+            s = definition.substr(posStart, posEnd - posStart);
 
             // The 1st frequency is before the first + or the /
             size_t pos_plus = s.find('+');
@@ -107,25 +111,22 @@ Tone::genBuffer(const std::string& definition)
 
             // If there is time or if it's unlimited
             if (time == 0)
-                count = sampleRate_;
+                count = sampleRate;
             else
-                count = (sampleRate_ * time) / 1000;
+                count = (sampleRate * time) / 1000;
 
             // Generate SAMPLING_RATE samples of sinus, buffer is the result
             genSin(bufferPos, freq1, freq2, count);
 
             // To concatenate the different buffers for each section.
-            size_ += count;
+            size += count;
             bufferPos += count;
         } /* end scope */
 
         posStart = posEnd + 1;
     } while (posStart < deflen);
 
-    assert(!buffer_);
-    buffer_ = new SFLDataFormat[size_];
-
-    memcpy(buffer_, &(*buffer.begin()), size_ * sizeof(SFLDataFormat)); // copy char, not SFLDataFormat.
+    buffer_->copy(buffer.data(), size); // fill the buffer
 }
 
 void
@@ -154,13 +155,13 @@ Tone::interpolate(double x) const
 }
 
 void
-Tone::genSin(SFLDataFormat* buffer, int frequency1, int frequency2, int nb)
+Tone::genSin(SFLAudioSample* buffer, int frequency1, int frequency2, int nb)
 {
     xhigher_ = 0.0;
     xlower_ = 0.0;
 
-    double sr = sampleRate_;
-    double tableSize = TABLE_LENGTH;
+    const double sr = (double)buffer_->getSampleRate();
+    static const double tableSize = TABLE_LENGTH;
 
     double N_h = sr / frequency1;
     double N_l = sr / frequency2;
diff --git a/daemon/src/audio/sound/tone.h b/daemon/src/audio/sound/tone.h
index 4c9bab9c9f61bd3e5e4d192a007e7ac679102f9d..586c61f5a215d943d0712d5893b2bb2f5944aa94 100644
--- a/daemon/src/audio/sound/tone.h
+++ b/daemon/src/audio/sound/tone.h
@@ -66,7 +66,7 @@ class Tone : public AudioLoop {
          * @param nb are the number of int16 (mono) to generate
          * by example nb=5 generate 10 int16, 5 for the left, 5 for the right
          */
-        void genSin(SFLDataFormat* buffer, int frequency1, int frequency2, int nb);
+        void genSin(SFLAudioSample* buffer, int frequency1, int frequency2, int nb);
 
         /**
          *
diff --git a/daemon/src/client/Makefile.am b/daemon/src/client/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..ee8f397a3a2d28aaee475e55c0fef64e3db22175
--- /dev/null
+++ b/daemon/src/client/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=dbus
diff --git a/daemon/src/client/android/JavaJNI2CJNI_Load.py b/daemon/src/client/android/JavaJNI2CJNI_Load.py
new file mode 100755
index 0000000000000000000000000000000000000000..0f3485af5b8091748b08e04b5fbdcc8a25875fa9
--- /dev/null
+++ b/daemon/src/client/android/JavaJNI2CJNI_Load.py
@@ -0,0 +1,85 @@
+#!/usr/bin/python
+import getopt, sys
+import re
+from string import Template
+
+def type_to_signature(itype):
+	if len(itype) > 2:
+		if itype[-2:] == '[]':
+			return "[%s" % type_to_signature(itype[:-2])
+	if itype == "int":
+		return "I"
+	if itype == "long":
+		return "J"
+	if itype == "void":
+		return "V"
+	if itype == "boolean":
+		return "Z"
+	if itype == "byte":
+		return "B"
+	if itype == "char":
+		return "C"
+	if itype == "short":
+		return "S"
+	if itype == "float":
+		return "F"
+	if itype == "double":
+		return "D"
+	if itype == "String":
+		return "Ljava/lang/String;"
+	if itype == "Object":
+		return "Ljava/lang/Object;"
+	return "Lcom/savoirfairelinux/sflphone/service/%s;" % itype
+
+def parse_java_file(input_stream, package, module):
+	outputs = []
+	package_prefix = "Java_%s_%sJNI" % (package.replace(".", "_"), module)
+	for line in input_stream:
+		definition = re.match(r'.*public final static native ([^\( ]*) ([^\)]*)\(([^)]*)\).*',line)
+		if definition is not None:
+			retour = definition.group(1)
+			name = definition.group(2)
+			args = definition.group(3)
+			args_sigs = []
+			args_frags = args.split(',')
+			for args_frag in args_frags:
+				argf = re.match(r'(\b)?([^ ]+) .*', args_frag.strip())
+				if argf is not None:
+					args_sigs.append(type_to_signature(argf.group(2)))
+			sig = "(%s)%s" % (''.join(args_sigs), type_to_signature(retour))
+			outputs.append("{\"%s\", \"%s\", (void*)& %s_%s}" % (name, sig, package_prefix, name.replace('_', '_1')))
+	return outputs
+
+def render_to_template(defs, template_string):
+	template = Template(template_string)
+	return template.substitute(defs= ",\r\n".join(defs) )
+
+
+if __name__ == "__main__":
+	try:
+		opts, args = getopt.getopt(sys.argv[1:], "i:o:t:m:p:", ["input=", "output=", "template=", "module=", "package="])
+	except getopt.GetoptError, err:
+		# print help information and exit:
+		print str(err) # will print something like "option -a not recognized"
+		sys.exit(2)
+	input_stream = None
+	output_file = None
+	template_string = None
+	package = ""
+	module = ""
+	for o, a in opts:
+		if o in ("-i", "--input"):
+			input_stream = open(a)
+		if o in ("-o", "--output"):
+			output_file = open(a, "w")
+		if o in ("-t", "--template"):
+			template_string = open(a).read()
+		if o in ("-m", "--module"):
+			module = a
+		if o in ("-p", "--package"):
+			package = a
+
+	defs = parse_java_file(input_stream, package, module)
+	output_file.write(render_to_template(defs, template_string))
+	output_file.close()
+	input_stream.close()
diff --git a/daemon/src/client/android/callmanager.cpp b/daemon/src/client/android/callmanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8a1456b6b8ec8b3221b2b12e7d2c657becb6b032
--- /dev/null
+++ b/daemon/src/client/android/callmanager.cpp
@@ -0,0 +1,500 @@
+/*
+ *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ *  Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
+ *  Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
+ *  Author: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
+ *
+ *  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, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+#include <vector>
+
+#include "global.h"
+#include "client/callmanager.h"
+#include "jni_callbacks.h"
+
+#include "sip/sipcall.h"
+#include "sip/sipvoiplink.h"
+#include "audio/audiolayer.h"
+#include "audio/audiortp/audio_rtp_factory.h"
+#if HAVE_ZRTP
+#include "audio/audiortp/audio_zrtp_session.h"
+#endif
+
+#include "logger.h"
+#include "manager.h"
+
+CallManager::CallManager()
+{}
+
+bool CallManager::placeCall(const std::string& accountID,
+                            const std::string& callID,
+                            const std::string& to)
+{
+    // Check if a destination number is available
+    if (to.empty()) {
+        DEBUG("No number entered - Call stopped");
+        return false;
+    } else {
+        return Manager::instance().outgoingCall(accountID, callID, to);
+    }
+}
+
+bool
+CallManager::refuse(const std::string& callID)
+{
+    return Manager::instance().refuseCall(callID);
+}
+
+bool
+CallManager::accept(const std::string& callID)
+{
+    return Manager::instance().answerCall(callID);
+}
+
+bool
+CallManager::hangUp(const std::string& callID)
+{
+    return Manager::instance().hangupCall(callID);
+}
+
+bool
+CallManager::hangUpConference(const std::string& confID)
+{
+    return Manager::instance().hangupConference(confID);
+}
+
+bool
+CallManager::hold(const std::string& callID)
+{
+    return Manager::instance().onHoldCall(callID);
+}
+
+bool
+CallManager::unhold(const std::string& callID)
+{
+    return Manager::instance().offHoldCall(callID);
+}
+
+bool
+CallManager::transfer(const std::string& callID, const std::string& to)
+{
+    return Manager::instance().transferCall(callID, to);
+}
+
+bool CallManager::attendedTransfer(const std::string& transferID, const std::string& targetID)
+{
+    return Manager::instance().attendedTransfer(transferID, targetID);
+}
+
+void CallManager::setVolume(const std::string& device, const double& value)
+{
+    AudioLayer *audiolayer = Manager::instance().getAudioDriver();
+
+    if(!audiolayer) {
+        ERROR("Audio layer not valid while updating volume");
+        return;
+    }
+
+    DEBUG("DBUS set volume for %s: %f", device.c_str(), value);
+
+    if (device == "speaker") {
+        audiolayer->setPlaybackGain((int)(value * 100.0));
+    } else if (device == "mic") {
+        audiolayer->setCaptureGain((int)(value * 100.0));
+    }
+
+    //volumeChanged(device, value);
+}
+
+double
+CallManager::getVolume(const std::string& device)
+{
+    AudioLayer *audiolayer = Manager::instance().getAudioDriver();
+
+    if(!audiolayer) {
+        ERROR("Audio layer not valid while updating volume");
+        return 0.0;
+    }
+
+    if (device == "speaker")
+        return audiolayer->getPlaybackGain() / 100.0;
+    else if (device == "mic")
+        return audiolayer->getCaptureGain() / 100.0;
+
+    return 0;
+}
+
+void
+CallManager::sendTextMessage(const std::string& callID, const std::string& message, const std::string& from)
+{
+#if HAVE_INSTANT_MESSAGING
+    Manager::instance().sendTextMessage(callID, message, from);
+#endif
+}
+
+void
+CallManager::sendTextMessage(const std::string& callID, const std::string& message)
+{
+#if HAVE_INSTANT_MESSAGING
+    try{
+        Manager::instance().sendTextMessage(callID, message, "Me");
+    }catch(...){
+        ERROR("Could not send \"%s\" text message to %s", message.c_str(), callID.c_str());
+    }
+
+#else
+    ERROR("Could not send \"%s\" text message to %s since SFLphone daemon does not support it, please recompile with instant messaging support", message.c_str(), callID.c_str());
+#endif
+}
+
+
+bool CallManager::toggleRecording(const std::string& id)
+{
+    return Manager::instance().toggleRecordingCall(id);
+}
+
+bool
+CallManager::joinParticipant(const std::string& sel_callID, const std::string& drag_callID)
+{
+    return Manager::instance().joinParticipant(sel_callID, drag_callID);
+}
+
+void
+CallManager::createConfFromParticipantList(const std::vector<std::string>& participants)
+{
+    Manager::instance().createConfFromParticipantList(participants);
+}
+
+void
+CallManager::removeConference(const std::string& conference_id)
+{
+    Manager::instance().removeConference(conference_id);
+}
+
+bool
+CallManager::addParticipant(const std::string& callID, const std::string& confID)
+{
+    return Manager::instance().addParticipant(callID, confID);
+}
+
+bool
+CallManager::addMainParticipant(const std::string& confID)
+{
+    return Manager::instance().addMainParticipant(confID);
+}
+
+bool
+CallManager::detachParticipant(const std::string& callID)
+{
+    return Manager::instance().detachParticipant(callID);
+}
+
+bool
+CallManager::joinConference(const std::string& sel_confID, const std::string& drag_confID)
+{
+    return Manager::instance().joinConference(sel_confID, drag_confID);
+}
+
+bool
+CallManager::holdConference(const std::string& confID)
+{
+    return Manager::instance().holdConference(confID);
+}
+
+bool
+CallManager::unholdConference(const std::string& confID)
+{
+    return Manager::instance().unHoldConference(confID);
+}
+
+bool
+CallManager::isConferenceParticipant(const std::string& call_id)
+{
+    return Manager::instance().isConferenceParticipant(call_id);
+}
+
+std::map<std::string, std::string>
+CallManager::getConferenceDetails(const std::string& callID)
+{
+    return Manager::instance().getConferenceDetails(callID);
+}
+
+std::vector<std::string>
+CallManager::getConferenceList()
+{
+    return Manager::instance().getConferenceList();
+}
+
+std::vector<std::string>
+CallManager::getParticipantList(const std::string& confID)
+{
+    return Manager::instance().getParticipantList(confID);
+}
+
+std::string
+CallManager::getConferenceId(const std::string& callID)
+{
+    return Manager::instance().getConferenceId(callID);
+}
+
+bool
+CallManager::startRecordedFilePlayback(const std::string& filepath)
+{
+    return Manager::instance().startRecordedFilePlayback(filepath);
+}
+
+void
+CallManager::stopRecordedFilePlayback(const std::string& filepath)
+{
+    Manager::instance().stopRecordedFilePlayback(filepath);
+}
+
+void
+CallManager::recordPlaybackSeek(const double& value)
+{
+    Manager::instance().recordingPlaybackSeek(value);
+}
+
+bool
+CallManager::getIsRecording(const std::string& callID)
+{
+    return Manager::instance().isRecording(callID);
+}
+
+std::string CallManager::getCurrentAudioCodecName(const std::string& callID)
+{
+    return Manager::instance().getCurrentAudioCodecName(callID);
+}
+
+std::map<std::string, std::string>
+CallManager::getCallDetails(const std::string& callID)
+{
+    return Manager::instance().getCallDetails(callID);
+}
+
+std::vector<std::string>
+CallManager::getCallList()
+{
+    return Manager::instance().getCallList();
+}
+
+void
+CallManager::playDTMF(const std::string& key)
+{
+    Manager::instance().sendDtmf(Manager::instance().getCurrentCallId(), key.data()[0]);
+}
+
+void
+CallManager::startTone(const int32_t& start , const int32_t& type)
+{
+    if (start) {
+        if (type == 0)
+            Manager::instance().playTone();
+        else
+            Manager::instance().playToneWithMessage();
+    } else
+        Manager::instance().stopTone();
+}
+
+// TODO: this will have to be adapted
+// for conferencing in order to get
+// the right pointer for the given
+// callID.
+#if HAVE_ZRTP
+sfl::AudioZrtpSession *
+CallManager::getAudioZrtpSession(const std::string& callID)
+{
+    // IP2IP profile is associated with IP2IP profile anyway
+    SIPVoIPLink * link = static_cast<SIPVoIPLink *>(Manager::instance().getAccountLink(SIPAccount::IP2IP_PROFILE));
+
+    if (!link)
+        throw CallManagerException("Failed to get sip link");
+
+    SIPCall *call;
+
+    try {
+        call = link->getSIPCall(callID);
+    } catch (const VoipLinkException &e) {
+        throw CallManagerException("Call id " + callID + " is not valid");
+    }
+
+    sfl::AudioZrtpSession * zSession = call->getAudioRtp().getAudioZrtpSession();
+
+    if (!zSession)
+        throw CallManagerException("Failed to get AudioZrtpSession");
+
+    return zSession;
+}
+#endif
+
+void
+CallManager::setSASVerified(const std::string& callID)
+{
+#if HAVE_ZRTP
+    try {
+        sfl::AudioZrtpSession * zSession;
+        zSession = getAudioZrtpSession(callID);
+        zSession->SASVerified();
+    } catch (...) {
+    }
+#else
+    ERROR("No zrtp support for %s, please recompile SFLphone with zrtp", callID.c_str());
+#endif
+}
+
+void
+CallManager::resetSASVerified(const std::string& callID)
+{
+#if HAVE_ZRTP
+    try {
+        sfl::AudioZrtpSession * zSession;
+        zSession = getAudioZrtpSession(callID);
+        zSession->resetSASVerified();
+    } catch (...) {
+    }
+#else
+    ERROR("No zrtp support for %s, please recompile SFLphone with zrtp", callID.c_str());
+#endif
+}
+
+void
+CallManager::setConfirmGoClear(const std::string& callID)
+{
+#if HAVE_ZRTP
+    try {
+        sfl::AudioZrtpSession * zSession;
+        zSession = getAudioZrtpSession(callID);
+        zSession->goClearOk();
+    } catch (...) {
+    }
+#else
+    ERROR("No zrtp support for %s, please recompile SFLphone with zrtp", callID.c_str());
+#endif
+}
+
+void
+CallManager::requestGoClear(const std::string& callID)
+{
+#if HAVE_ZRTP
+    try {
+        sfl::AudioZrtpSession * zSession;
+        zSession = getAudioZrtpSession(callID);
+        zSession->requestGoClear();
+    } catch (...) {
+    }
+#else
+    ERROR("No zrtp support for %s, please recompile SFLphone with zrtp", callID.c_str());
+#endif
+}
+
+void
+CallManager::acceptEnrollment(const std::string& callID, const bool& accepted)
+{
+#if HAVE_ZRTP
+    try {
+        sfl::AudioZrtpSession * zSession;
+        zSession = getAudioZrtpSession(callID);
+        zSession->acceptEnrollment(accepted);
+    } catch (...) {
+    }
+#else
+    ERROR("No zrtp support for %s, please recompile SFLphone with zrtp", callID.c_str());
+#endif
+}
+
+void CallManager::callStateChanged(const std::string& callID, const std::string& state)
+{
+    on_call_state_changed_wrapper(callID, state);
+}
+
+void CallManager::transferFailed()
+{
+
+}
+
+void CallManager::transferSucceeded()
+{
+
+}
+
+void CallManager::recordPlaybackStopped(const std::string& path)
+{
+
+}
+
+void CallManager::voiceMailNotify(const std::string& callID, const std::string& nd_msg)
+{
+
+}
+
+void CallManager::incomingMessage(const std::string& ID, const std::string& from, const std::string& msg)
+{
+    on_incoming_message_wrapper(ID, from, msg);
+}
+
+void CallManager::incomingCall(const std::string& accountID, const std::string& callID, const std::string& from)
+{
+    on_incoming_call_wrapper(accountID, callID, from);
+}
+
+void CallManager::recordPlaybackFilepath(const std::string& id, const std::string& filename)
+{
+    on_record_playback_filepath_wrapper(id, filename);
+}
+
+void CallManager::conferenceCreated(const std::string& confID)
+{
+    on_conference_created_wrapper(confID);
+}
+
+void CallManager::conferenceChanged(const std::string& confID,const std::string& state)
+{
+    on_conference_state_changed_wrapper(confID, state);
+}
+
+void CallManager::conferenceRemoved(const std::string& confID)
+{
+    on_conference_removed_wrapper(confID);
+}
+
+void CallManager::newCallCreated(const std::string& accountID, const std::string& callID, const std::string& to)
+{
+    on_new_call_created_wrapper(accountID, callID, to);
+}
+
+void CallManager::registrationStateChanged(const std::string& accoundID, const std::string& state, const int32_t& code)
+{
+    on_account_state_changed_with_code_wrapper(accoundID, state, code);
+}
+
+void CallManager::sipCallStateChanged(const std::string& accoundID, const std::string& state, const int32_t& code)
+{
+
+}
+
+void CallManager::updatePlaybackScale(const int32_t&, const int32_t&)
+{
+}
diff --git a/daemon/src/client/android/callmanager.i b/daemon/src/client/android/callmanager.i
new file mode 100644
index 0000000000000000000000000000000000000000..33998b9cddda1e8867c77b2d2c5c89bc1a3d7e94
--- /dev/null
+++ b/daemon/src/client/android/callmanager.i
@@ -0,0 +1,256 @@
+/*
+ *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
+ *  Author: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
+ *          Alexandre Lision <alexnadre.L@savoirfairelinux.com>
+ *  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, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+%header %{
+
+#include "client/callmanager.h"
+
+
+typedef struct callmanager_callback
+{
+    void (*on_new_call_created)(const std::string& accountID,
+                                const std::string& callID,
+                                const std::string& to);
+
+    void (*on_call_state_changed)(const std::string& callID,
+                                  const std::string& state);
+
+    void (*on_incoming_call)(const std::string& accountID,
+                             const std::string& callID,
+                             const std::string& from);
+
+    void (*on_transfer_state_changed) (const std::string& result);
+
+    void (*on_conference_created) (const std::string& confID);
+
+    void (*on_conference_removed) (const std::string& confID);
+
+    void (*on_conference_state_changed) (const std::string& confID,
+                                          const std::string& state);
+
+    void (*on_incoming_message) (const std::string& ID,
+                                    const std::string& from,
+                                    const std::string& msg);
+
+    void (*on_record_playback_filepath) (const std::string& id,
+                                         const std::string& filename);
+} callmanager_callback_t;
+
+
+class Callback {
+public:
+    virtual ~Callback() {}
+
+    virtual void on_new_call_created(const std::string& arg1,
+                                     const std::string& arg2,
+                                     const std::string& arg3) {}
+
+    virtual void on_call_state_changed(const std::string& arg1,
+                                       const std::string& arg2) {}
+
+    virtual void on_incoming_call(const std::string& arg1,
+                                  const std::string& arg2,
+                                  const std::string& arg3) {}
+
+    virtual void on_transfer_state_changed (const std::string& arg1) {}
+
+    virtual void on_conference_created (const std::string& arg1) {}
+
+    virtual void on_conference_removed (const std::string& arg1) {}
+
+    virtual void on_conference_state_changed (const std::string& arg1,
+                                            const std::string& arg2) {}
+
+    virtual void on_incoming_message(const std::string& ID,
+                                    const std::string& from,
+                                    const std::string& msg) {}
+
+    virtual void on_record_playback_filepath(const std::string& id,
+                                              const std::string& filename) {}
+};
+
+
+static Callback* registeredCallbackObject = NULL;
+
+void on_new_call_created_wrapper (const std::string& accountID,
+                                  const std::string& callID,
+                                  const std::string& to) {
+    registeredCallbackObject->on_new_call_created(accountID, callID, to);
+}
+
+void on_call_state_changed_wrapper(const std::string& callID,
+                           const std::string& state) {
+    registeredCallbackObject->on_call_state_changed(callID, state);
+}
+
+void on_incoming_call_wrapper (const std::string& accountID,
+                               const std::string& callID,
+                               const std::string& from) {
+    registeredCallbackObject->on_incoming_call(accountID, callID, from);
+}
+
+void on_transfer_state_changed_wrapper (const std::string& result) {
+    registeredCallbackObject->on_transfer_state_changed(result);
+}
+
+void on_conference_created_wrapper (const std::string& confID) {
+    registeredCallbackObject->on_conference_created(confID);
+}
+
+void on_conference_removed_wrapper (const std::string& confID) {
+    registeredCallbackObject->on_conference_removed(confID);
+}
+
+void on_conference_state_changed_wrapper (const std::string& confID,
+                                          const std::string& state) {
+    registeredCallbackObject->on_conference_state_changed(confID, state);
+}
+
+void on_incoming_message_wrapper(const std::string& ID, const std::string& from, const std::string& msg) {
+  registeredCallbackObject->on_incoming_message(ID, from, msg);
+}
+
+void on_record_playback_filepath_wrapper(const std::string& id, const std::string& filename){
+  registeredCallbackObject->on_record_playback_filepath(id, filename);
+}
+
+static struct callmanager_callback wrapper_callback_struct = {
+    &on_new_call_created_wrapper,
+    &on_call_state_changed_wrapper,
+    &on_incoming_call_wrapper,
+    &on_transfer_state_changed_wrapper,
+    &on_conference_created_wrapper,
+    &on_conference_removed_wrapper,
+    &on_conference_state_changed_wrapper,
+    &on_incoming_message_wrapper,
+    &on_record_playback_filepath_wrapper,
+};
+
+void setCallbackObject(Callback* callback) {
+    registeredCallbackObject = callback;
+}
+
+%}
+
+%feature("director") Callback;
+
+class CallManager {
+public:
+    bool placeCall(const std::string& accountID, const std::string& callID, const std::string& to);
+
+    bool refuse(const std::string& callID);
+    bool accept(const std::string& callID);
+    bool hangUp(const std::string& callID);
+    bool hold(const std::string& callID);
+    bool unhold(const std::string& callID);
+    bool transfer(const std::string& callID, const std::string& to);
+    bool attendedTransfer(const std::string& transferID, const std::string& targetID);
+    std::map< std::string, std::string > getCallDetails(const std::string& callID);
+    std::vector< std::string > getCallList();
+
+    /* Conference related methods */
+    void removeConference(const std::string& conference_id);
+    bool joinParticipant(const std::string& sel_callID, const std::string& drag_callID);
+    void createConfFromParticipantList(const std::vector< std::string >& participants);
+    bool isConferenceParticipant(const std::string& call_id);
+    bool addParticipant(const std::string& callID, const std::string& confID);
+    bool addMainParticipant(const std::string& confID);
+    bool detachParticipant(const std::string& callID);
+    bool joinConference(const std::string& sel_confID, const std::string& drag_confID);
+    bool hangUpConference(const std::string& confID);
+    bool holdConference(const std::string& confID);
+    bool unholdConference(const std::string& confID);
+    std::vector<std::string> getConferenceList();
+    std::vector<std::string> getParticipantList(const std::string& confID);
+    std::string getConferenceId(const std::string& callID);
+    std::map<std::string, std::string> getConferenceDetails(const std::string& callID);
+
+    /* File Playback methods */
+    bool startRecordedFilePlayback(const std::string& filepath);
+    void stopRecordedFilePlayback(const std::string& filepath);
+
+    /* General audio methods */
+    void setVolume(const std::string& device, const double& value);
+    double getVolume(const std::string& device);
+    bool toggleRecording(const std::string& callID);
+    void recordPlaybackSeek(const double& value);
+    bool getIsRecording(const std::string& callID);
+    std::string getCurrentAudioCodecName(const std::string& callID);
+    void playDTMF(const std::string& key);
+    void startTone(const int32_t& start, const int32_t& type);
+
+    /* Security related methods */
+    void setSASVerified(const std::string& callID);
+    void resetSASVerified(const std::string& callID);
+    void setConfirmGoClear(const std::string& callID);
+    void requestGoClear(const std::string& callID);
+    void acceptEnrollment(const std::string& callID, const bool& accepted);
+
+    /* Instant messaging */
+    void sendTextMessage(const std::string& callID, const std::string& message);
+};
+
+class Callback {
+public:
+    virtual ~Callback();
+
+    virtual void on_new_call_created(const std::string& arg1,
+                                     const std::string& arg2,
+                                     const std::string& arg3);
+
+    virtual void on_call_state_changed(const std::string& arg1,
+                                       const std::string& arg2);
+
+    virtual void on_incoming_call(const std::string& arg1,
+                                  const std::string& arg2,
+                                  const std::string& arg3);
+
+    virtual void on_transfer_state_changed(const std::string& arg1);
+
+    virtual void on_conference_created(const std::string& arg1);
+
+    virtual void on_conference_removed(const std::string& arg1);
+
+    virtual void on_conference_state_changed(const std::string& arg1,
+                                              const std::string& arg2);
+
+    virtual void on_incoming_message(const std::string& ID,
+                                    const std::string& from,
+                                    const std::string& msg);
+
+    virtual void on_record_playback_filepath(const std::string& id,
+                                            const std::string& filename);
+};
+
+static Callback* registeredCallbackObject = NULL;
+
+void setCallbackObject(Callback* callback) {
+    registeredCallbackObject = callback;
+}
diff --git a/daemon/src/client/android/client.cpp b/daemon/src/client/android/client.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5df2630a2101bdf7adb456329271bcaa120c53da
--- /dev/null
+++ b/daemon/src/client/android/client.cpp
@@ -0,0 +1,69 @@
+/*
+ *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ *  Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "client/client.h"
+#include "client/callmanager.h"
+#include "client/configurationmanager.h"
+
+Client::Client() : callManager_(new CallManager)
+    , configurationManager_(new ConfigurationManager)
+    , instanceManager_(0)
+    , dispatcher_(0)
+#ifdef SFL_VIDEO
+    , videoControls_(0)
+#endif
+#ifdef USE_NETWORKMANAGER
+    , networkManager_(0)
+#endif
+{}
+
+Client::~Client()
+{
+#ifdef USE_NETWORKMANAGER
+    delete networkManager_;
+#endif
+#ifdef SFL_VIDEO
+    delete videoControls_;
+#endif
+    delete dispatcher_;
+    delete instanceManager_;
+    delete configurationManager_;
+    delete callManager_;
+}
+
+void Client::event_loop()
+{}
+
+void Client::exit()
+{}
diff --git a/daemon/src/client/android/configurationmanager.cpp b/daemon/src/client/android/configurationmanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5d3293e161a3383c3dcac2d4855ef2d132e8bf41
--- /dev/null
+++ b/daemon/src/client/android/configurationmanager.cpp
@@ -0,0 +1,488 @@
+/*
+ *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
+ *  Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
+ *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *  Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@savoirfairelinux.com>
+ *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *
+ *  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, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cerrno>
+#include <sstream>
+
+#include "client/configurationmanager.h"
+#include "jni_callbacks.h"
+#include "account_schema.h"
+#include "manager.h"
+#include "sip/sipvoiplink.h"
+#include "sip/siptransport.h"
+#include "logger.h"
+#include "fileutils.h"
+#include "sip/sipaccount.h"
+#include "history/historynamecache.h"
+#include "audio/audiolayer.h"
+
+namespace {
+    const char* SERVER_PATH = "/org/sflphone/SFLphone/ConfigurationManager";
+}
+
+ConfigurationManager::ConfigurationManager() {}
+
+std::map<std::string, std::string> ConfigurationManager::getIp2IpDetails()
+{
+    std::map<std::string, std::string> ip2ipAccountDetails;
+    SIPAccount *sipaccount = Manager::instance().getIP2IPAccount();
+
+    if (!sipaccount) {
+        ERROR("Could not find IP2IP account");
+        return ip2ipAccountDetails;
+    } else
+        return sipaccount->getIp2IpDetails();
+
+    std::map<std::string, std::string> tlsSettings(getTlsSettings());
+    std::copy(tlsSettings.begin(), tlsSettings.end(),
+              std::inserter(ip2ipAccountDetails, ip2ipAccountDetails.end()));
+
+    return ip2ipAccountDetails;
+}
+
+
+std::map<std::string, std::string> ConfigurationManager::getAccountDetails(
+    const std::string& accountID)
+{
+    return Manager::instance().getAccountDetails(accountID);
+}
+
+std::map<std::string, std::string>
+ConfigurationManager::getTlsSettingsDefault()
+{
+    std::stringstream portstr;
+    portstr << DEFAULT_SIP_TLS_PORT;
+
+    std::map<std::string, std::string> tlsSettingsDefault;
+    tlsSettingsDefault[CONFIG_TLS_LISTENER_PORT] = portstr.str();
+    tlsSettingsDefault[CONFIG_TLS_CA_LIST_FILE] = "";
+    tlsSettingsDefault[CONFIG_TLS_CERTIFICATE_FILE] = "";
+    tlsSettingsDefault[CONFIG_TLS_PRIVATE_KEY_FILE] = "";
+    tlsSettingsDefault[CONFIG_TLS_PASSWORD] = "";
+    tlsSettingsDefault[CONFIG_TLS_METHOD] = "TLSv1";
+    tlsSettingsDefault[CONFIG_TLS_CIPHERS] = "";
+    tlsSettingsDefault[CONFIG_TLS_SERVER_NAME] = "";
+    tlsSettingsDefault[CONFIG_TLS_VERIFY_SERVER] = "true";
+    tlsSettingsDefault[CONFIG_TLS_VERIFY_CLIENT] = "true";
+    tlsSettingsDefault[CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] = "true";
+    tlsSettingsDefault[CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC] = "2";
+    tlsSettingsDefault[CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC] = "0";
+
+    return tlsSettingsDefault;
+}
+
+std::map<std::string, std::string> ConfigurationManager::getTlsSettings()
+{
+    std::map<std::string, std::string> tlsSettings;
+
+    SIPAccount *sipaccount = Manager::instance().getIP2IPAccount();
+
+    if (!sipaccount)
+        return tlsSettings;
+
+    return sipaccount->getTlsSettings();
+}
+
+void ConfigurationManager::setTlsSettings(const std::map<std::string, std::string>& details)
+{
+    SIPAccount *sipaccount = Manager::instance().getIP2IPAccount();
+
+    if (!sipaccount) {
+        DEBUG("No valid account in set TLS settings");
+        return;
+    }
+
+    sipaccount->setTlsSettings(details);
+
+    // Manager::instance().saveConfig();
+
+    // Update account details to the client side
+    // accountsChanged();
+}
+
+
+void ConfigurationManager::setAccountDetails(const std::string& accountID, const std::map<std::string, std::string>& details)
+{
+    Manager::instance().setAccountDetails(accountID, details);
+}
+
+void ConfigurationManager::sendRegister(const std::string& accountID, const bool& enable)
+{
+    Manager::instance().sendRegister(accountID, enable);
+}
+
+void ConfigurationManager::registerAllAccounts()
+{
+    Manager::instance().registerAllAccounts();
+}
+
+///This function is used as a base for new accounts for clients that support it
+std::map<std::string, std::string> ConfigurationManager::getAccountTemplate()
+{
+   std::map<std::string, std::string> accTemplate;
+   accTemplate[ CONFIG_LOCAL_PORT                  ] = CONFIG_DEFAULT_LOCAL_PORT;
+   accTemplate[ CONFIG_PUBLISHED_PORT              ] = CONFIG_DEFAULT_PUBLISHED_PORT;
+   accTemplate[ CONFIG_PUBLISHED_SAMEAS_LOCAL      ] = CONFIG_DEFAULT_PUBLISHED_SAMEAS_LOCAL;
+   accTemplate[ CONFIG_INTERFACE                   ] = CONFIG_DEFAULT_INTERFACE;
+   accTemplate[ CONFIG_ACCOUNT_REGISTRATION_EXPIRE ] = CONFIG_DEFAULT_REGISTRATION_EXPIRE;
+   return accTemplate;
+}
+
+std::string ConfigurationManager::addAccount(const std::map<std::string, std::string>& details)
+{
+    return Manager::instance().addAccount(details);
+}
+
+void ConfigurationManager::removeAccount(const std::string& accoundID)
+{
+    return Manager::instance().removeAccount(accoundID);
+}
+
+/**
+ * Send the list of all codecs loaded to the client through DBus.
+ * Can stay global, as only the active codecs will be set per accounts
+ */
+std::vector<int32_t> ConfigurationManager::getAudioCodecList()
+{
+    std::vector<int32_t> list(Manager::instance().audioCodecFactory.getCodecList());
+
+    // if (list.empty())
+    //     errorAlert(CODECS_NOT_LOADED);
+
+    return list;
+}
+
+std::vector<std::string> ConfigurationManager::getAccountList()
+{
+    return Manager::instance().getAccountList();
+}
+
+std::vector<std::string> ConfigurationManager::getSupportedTlsMethod()
+{
+    std::vector<std::string> method;
+    method.push_back("Default");
+    method.push_back("TLSv1");
+    method.push_back("SSLv3");
+    method.push_back("SSLv23");
+    return method;
+}
+
+std::vector<std::string> ConfigurationManager::getAudioCodecDetails(const int32_t& payload)
+{
+    std::vector<std::string> result(Manager::instance().audioCodecFactory.getCodecSpecifications(payload));
+
+    // if (result.empty())
+    //    errorAlert(CODECS_NOT_LOADED);
+
+    return result;
+}
+
+std::vector<int32_t> ConfigurationManager::getActiveAudioCodecList(const std::string& accountID)
+{
+    Account *acc = Manager::instance().getAccount(accountID);
+
+    if (acc)
+        return acc->getActiveAudioCodecs();
+    else {
+        ERROR("Could not find account %s, returning default", accountID.c_str());
+        return Account::getDefaultAudioCodecs();
+    }
+}
+
+void ConfigurationManager::setActiveAudioCodecList(const std::vector<std::string>& list, const std::string& accountID)
+{
+    Account *acc = Manager::instance().getAccount(accountID);
+
+    if (acc) {
+        acc->setActiveAudioCodecs(list);
+        Manager::instance().saveConfig();
+    } else {
+        ERROR("Could not find account %s", accountID.c_str());
+    }
+}
+
+std::vector<std::string> ConfigurationManager::getAudioPluginList()
+{
+    std::vector<std::string> v;
+
+    v.push_back(PCM_DEFAULT);
+    v.push_back(PCM_DMIX_DSNOOP);
+
+    return v;
+}
+
+void ConfigurationManager::setAudioPlugin(const std::string& audioPlugin)
+{
+    return Manager::instance().setAudioPlugin(audioPlugin);
+}
+
+std::vector<std::string> ConfigurationManager::getAudioOutputDeviceList()
+{
+    return Manager::instance().getAudioOutputDeviceList();
+}
+
+std::vector<std::string> ConfigurationManager::getAudioInputDeviceList()
+{
+    return Manager::instance().getAudioInputDeviceList();
+}
+
+void ConfigurationManager::setAudioOutputDevice(const int32_t& index)
+{
+    return Manager::instance().setAudioDevice(index, AudioLayer::SFL_PCM_PLAYBACK);
+}
+
+void ConfigurationManager::setAudioInputDevice(const int32_t& index)
+{
+    return Manager::instance().setAudioDevice(index, AudioLayer::SFL_PCM_CAPTURE);
+}
+
+void ConfigurationManager::setAudioRingtoneDevice(const int32_t& index)
+{
+    return Manager::instance().setAudioDevice(index, AudioLayer::SFL_PCM_RINGTONE);
+}
+
+std::vector<std::string> ConfigurationManager::getCurrentAudioDevicesIndex()
+{
+    return Manager::instance().getCurrentAudioDevicesIndex();
+}
+
+int32_t ConfigurationManager::getAudioDeviceIndex(const std::string& name)
+{
+    return Manager::instance().getAudioDeviceIndex(name);
+}
+
+std::string ConfigurationManager::getCurrentAudioOutputPlugin()
+{
+    DEBUG("Get audio plugin %s", Manager::instance().getCurrentAudioOutputPlugin().c_str());
+
+    return Manager::instance().getCurrentAudioOutputPlugin();
+}
+
+std::string ConfigurationManager::getNoiseSuppressState()
+{
+    return Manager::instance().getNoiseSuppressState();
+}
+
+void ConfigurationManager::setNoiseSuppressState(const std::string& state)
+{
+    Manager::instance().setNoiseSuppressState(state);
+}
+
+std::string ConfigurationManager::getEchoCancelState()
+{
+    return Manager::instance().getEchoCancelState() ? "enabled" : "disabled";
+}
+
+std::map<std::string, std::string> ConfigurationManager::getRingtoneList()
+{
+    std::map<std::string, std::string> ringToneList;
+    std::string r_path(fileutils::get_data_dir());
+    struct dirent **namelist;
+    int n = scandir(r_path.c_str(), &namelist, 0, alphasort);
+    if (n == -1) {
+        ERROR("%s", strerror(errno));
+        return ringToneList;
+    }
+
+    while (n--) {
+        if (strcmp(namelist[n]->d_name, ".") and strcmp(namelist[n]->d_name, "..")) {
+            std::string file(namelist[n]->d_name);
+
+            if (file.find(".wav") != std::string::npos)
+                file.replace(file.find(".wav"), 4, "");
+            else
+                file.replace(file.size() - 3, 3, "");
+            if (file[0] <= 0x7A and file[0] >= 0x61) file[0] = file[0] - 32;
+            ringToneList[r_path + namelist[n]->d_name] = file;
+        }
+        free(namelist[n]);
+    }
+    free(namelist);
+    return ringToneList;
+}
+
+void ConfigurationManager::setEchoCancelState(const std::string& state)
+{
+    Manager::instance().setEchoCancelState(state);
+}
+
+int32_t ConfigurationManager::isIax2Enabled()
+{
+    return HAVE_IAX;
+}
+
+std::string ConfigurationManager::getRecordPath()
+{
+    return Manager::instance().audioPreference.getRecordPath();
+}
+
+void ConfigurationManager::setRecordPath(const std::string& recPath)
+{
+    Manager::instance().audioPreference.setRecordPath(recPath);
+}
+
+bool ConfigurationManager::getIsAlwaysRecording()
+{
+    return Manager::instance().getIsAlwaysRecording();
+}
+
+void ConfigurationManager::setIsAlwaysRecording(const bool& rec)
+{
+    Manager::instance().setIsAlwaysRecording(rec);
+}
+
+/*
+void ConfigurationManager::setRecordingCall(const std::string& id)
+{
+    Manager::instance().setRecordingCall(id);
+}
+*/
+int32_t ConfigurationManager::getHistoryLimit()
+{
+    return Manager::instance().getHistoryLimit();
+}
+
+void ConfigurationManager::clearHistory()
+{
+    return Manager::instance().clearHistory();
+}
+
+void ConfigurationManager::setHistoryLimit(const int32_t& days)
+{
+    Manager::instance().setHistoryLimit(days);
+}
+
+void ConfigurationManager::setAudioManager(const std::string& api)
+{
+    Manager::instance().setAudioManager(api);
+}
+
+std::string ConfigurationManager::getAudioManager()
+{
+    return Manager::instance().getAudioManager();
+}
+
+std::map<std::string, std::string> ConfigurationManager::getHookSettings()
+{
+    return Manager::instance().hookPreference.toMap();
+}
+
+void ConfigurationManager::setHookSettings(const std::map<std::string,
+        std::string>& settings)
+{
+    Manager::instance().hookPreference = HookPreference(settings);
+}
+
+void ConfigurationManager::setAccountsOrder(const std::string& order)
+{
+    Manager::instance().setAccountsOrder(order);
+}
+
+std::vector<std::map<std::string, std::string> > ConfigurationManager::getHistory()
+{
+    return Manager::instance().getHistory();
+}
+
+std::string
+ConfigurationManager::getAddrFromInterfaceName(const std::string& interface)
+{
+    return SipTransport::getInterfaceAddrFromName(interface);
+}
+
+std::vector<std::string> ConfigurationManager::getAllIpInterface()
+{
+    return SipTransport::getAllIpInterface();
+}
+
+std::vector<std::string> ConfigurationManager::getAllIpInterfaceByName()
+{
+    return SipTransport::getAllIpInterfaceByName();
+}
+
+std::map<std::string, std::string> ConfigurationManager::getShortcuts()
+{
+    return Manager::instance().shortcutPreferences.getShortcuts();
+}
+
+void ConfigurationManager::setShortcuts(
+    const std::map<std::string, std::string>& shortcutsMap)
+{
+    Manager::instance().shortcutPreferences.setShortcuts(shortcutsMap);
+    Manager::instance().saveConfig();
+}
+
+std::vector<std::map<std::string, std::string> > ConfigurationManager::getCredentials(
+    const std::string& accountID)
+{
+    SIPAccount *account = Manager::instance().getSipAccount(accountID);
+    std::vector<std::map<std::string, std::string> > credentialInformation;
+
+    if (!account)
+        return credentialInformation;
+    else
+        return account->getCredentials();
+}
+
+void ConfigurationManager::setCredentials(const std::string& accountID,
+        const std::vector<std::map<std::string, std::string> >& details)
+{
+    SIPAccount *account = Manager::instance().getSipAccount(accountID);
+    if (account)
+        account->setCredentials(details);
+}
+
+
+
+void ConfigurationManager::accountsChanged()
+{
+    on_accounts_changed_wrapper();
+}
+
+void ConfigurationManager::historyChanged()
+{
+
+}
+
+void ConfigurationManager::stunStatusFailure(const std::string& accoundID)
+{
+
+}
+
+void ConfigurationManager::registrationStateChanged(const std::string& accoundID, int const& state)
+{
+    on_account_state_changed_wrapper(accoundID, state);
+}
diff --git a/daemon/src/client/android/configurationmanager.i b/daemon/src/client/android/configurationmanager.i
new file mode 100644
index 0000000000000000000000000000000000000000..479da00cf7c99f1b7759773eb0890fbe4b16f7b0
--- /dev/null
+++ b/daemon/src/client/android/configurationmanager.i
@@ -0,0 +1,162 @@
+/*
+ *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *  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, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+%header %{
+#include "client/configurationmanager.h"
+
+typedef struct configurationmanager_callback
+{
+    void (*on_accounts_changed)(void);
+    void (*on_account_state_changed)(const std::string& accoundID, const int32_t& state);
+    void (*on_account_state_changed_with_code)(const std::string& accoundID, const std::string& state, const int32_t& code);
+} configurationmanager_callback_t;
+
+
+class ConfigurationCallback {
+public:
+    virtual ~ConfigurationCallback() {}
+    virtual void on_accounts_changed(void) {}
+    virtual void on_account_state_changed(const std::string& accoundID, const int32_t& state) {}
+    virtual void on_account_state_changed_with_code(const std::string& accoundID, const std::string& state, const int32_t& code) {}
+};
+
+static ConfigurationCallback *registeredConfigurationCallbackObject = NULL;
+
+void on_accounts_changed_wrapper (void) {
+    registeredConfigurationCallbackObject->on_accounts_changed();
+}
+
+void on_account_state_changed_wrapper (const std::string& accoundID, const int32_t& state) {
+    registeredConfigurationCallbackObject->on_account_state_changed(accoundID, state);
+}
+
+void on_account_state_changed_with_code_wrapper (const std::string& accoundID, const std::string& state, const int32_t& code) {
+    registeredConfigurationCallbackObject->on_account_state_changed_with_code(accoundID, state, code);
+}
+
+static struct configurationmanager_callback wrapper_configurationcallback_struct = {
+    &on_accounts_changed_wrapper,
+    &on_account_state_changed_wrapper,
+    &on_account_state_changed_with_code_wrapper
+};
+
+void setConfigurationCallbackObject(ConfigurationCallback *callback) {
+    registeredConfigurationCallbackObject = callback;
+}
+
+%}
+
+%feature("director") ConfigurationCallback;
+
+class ConfigurationManager {
+public:
+    std::map< std::string, std::string > getAccountDetails(const std::string& accountID);
+    void setAccountDetails(const std::string& accountID, const std::map< std::string, std::string >& details);
+    std::map<std::string, std::string> getAccountTemplate();
+    std::string addAccount(const std::map< std::string, std::string >& details);
+    void removeAccount(const std::string& accoundID);
+    std::vector< std::string > getAccountList();
+    void sendRegister(const std::string& accoundID, const bool& enable);
+    void registerAllAccounts(void);
+
+    std::map< std::string, std::string > getTlsSettingsDefault();
+
+    std::vector< int32_t > getAudioCodecList();
+    std::vector< std::string > getSupportedTlsMethod();
+    std::vector< std::string > getAudioCodecDetails(const int32_t& payload);
+    std::vector< int32_t > getActiveAudioCodecList(const std::string& accountID);
+
+    void setActiveAudioCodecList(const std::vector< std::string >& list, const std::string& accountID);
+
+    std::vector< std::string > getAudioPluginList();
+    void setAudioPlugin(const std::string& audioPlugin);
+    std::vector< std::string > getAudioOutputDeviceList();
+    void setAudioOutputDevice(const int32_t& index);
+    void setAudioInputDevice(const int32_t& index);
+    void setAudioRingtoneDevice(const int32_t& index);
+    std::vector< std::string > getAudioInputDeviceList();
+    std::vector< std::string > getCurrentAudioDevicesIndex();
+    int32_t getAudioDeviceIndex(const std::string& name);
+    std::string getCurrentAudioOutputPlugin();
+    std::string getNoiseSuppressState();
+    void setNoiseSuppressState(const std::string& state);
+    std::string getEchoCancelState();
+    void setEchoCancelState(const std::string& state);
+
+    std::map<std::string, std::string> getRingtoneList();
+
+    std::string getAudioManager();
+    void setAudioManager(const std::string& api);
+
+    int32_t isIax2Enabled();
+    std::string getRecordPath();
+    void setRecordPath(const std::string& recPath);
+    bool getIsAlwaysRecording();
+    void setIsAlwaysRecording(const bool& rec);
+
+    void setHistoryLimit(const int32_t& days);
+    int32_t getHistoryLimit();
+    void clearHistory();
+
+    void setAccountsOrder(const std::string& order);
+
+    std::map<std::string, std::string> getHookSettings();
+    void setHookSettings(const std::map<std::string, std::string>& settings);
+
+    std::vector<std::map<std::string, std::string> > getHistory();
+
+    std::map<std::string, std::string> getTlsSettings();
+    void setTlsSettings(const std::map< std::string, std::string >& details);
+    std::map< std::string, std::string > getIp2IpDetails();
+
+    std::vector< std::map< std::string, std::string > > getCredentials(const std::string& accountID);
+    void setCredentials(const std::string& accountID, const std::vector< std::map< std::string, std::string > >& details);
+
+    std::string getAddrFromInterfaceName(const std::string& interface);
+
+    std::vector<std::string> getAllIpInterface();
+    std::vector<std::string> getAllIpInterfaceByName();
+
+    std::map<std::string, std::string> getShortcuts();
+    void setShortcuts(const std::map<std::string, std::string> &shortcutsMap);
+};
+
+class ConfigurationCallback {
+public:
+    virtual ~ConfigurationCallback();
+    virtual void on_accounts_changed(void);
+    virtual void on_account_state_changed(const std::string& accoundID, const int32_t& state);
+    virtual void on_account_state_changed_with_code(const std::string& accoundID, const std::string& state, const int32_t& code);
+};
+
+static ConfigurationCallback *registeredConfigurationCallbackObject = NULL;
+
+void setConfigurationCallbackObject(ConfigurationCallback *callback) {
+    registeredConfigurationCallbackObject = callback;
+}
diff --git a/daemon/src/client/android/jni-xml2cpp.py b/daemon/src/client/android/jni-xml2cpp.py
new file mode 100755
index 0000000000000000000000000000000000000000..067f488d3f644bbfc5afefe7c68c3938b0568328
--- /dev/null
+++ b/daemon/src/client/android/jni-xml2cpp.py
@@ -0,0 +1,85 @@
+#!/usr/bin/python
+
+#
+# PACKAGE DEPENDENCIES: python python-lxml
+#
+
+#import easy to use xml parser called minidom:
+from lxml import etree
+#from copy import deepcopy
+from lxml import objectify
+import re, sys, getopt
+
+def rreplace(s, old, new, occurrence):
+    li = s.rsplit(old, occurrence)
+    return new.join(li)
+
+def usage():
+    print "jni-xml2cpp.py --file <file> | -i <file>"
+
+# main
+inputfile = "./dbus/callmanager-introspec.xml"
+outputfile = "./dbus/callmanager-jni.h"
+try:
+    opts, args = getopt.getopt(sys.argv[1:], "hi:o:", ["help", "input=", "output="])
+except getopt.GetoptError, err:
+    usage()
+    print str(err)
+    #print opts
+    sys.exit(2)
+
+for opt, arg in opts:
+    if opt in ("-h", "--help"):
+        usage()
+        sys.exit(0)
+    elif opt in ("-i", "--input"):
+        inputfile = arg
+    elif opt in ("-o", "--output"):
+        outputfile = arg
+    else:
+        print "error: argument not recognized"
+        sys.exit(3)
+
+print "inputfile = %s" % (inputfile)
+print "outputfile = %s" % (outputfile)
+source = "".join(args)
+
+# lxml.objectify
+# FIXME relative path
+cm_obj_tree = objectify.parse(inputfile)
+cm_obj_root = cm_obj_tree.getroot()
+# http://www.skymind.com/~ocrow/python_string/
+# method 4: list of strings
+prototype = []
+# iteration on methods
+for meth in cm_obj_root.interface.iter(tag="method"):
+# iteration on arguments
+    prototype.append(meth.get("name"))
+    prototype.append("(")
+    for argum in meth.iter(tag="arg"):
+        name = argum.get("name")
+        typ = argum.get("type")
+# FIXME
+        if typ == 's':
+            prototype.append("string %s, " % (name))
+        elif typ == 'i':
+            prototype.append("int %s, " % (name))
+        elif typ == 'd':
+            prototype.append("unsigned int %s, " % (name))
+        elif typ == 'as':
+            prototype.append("std::vector< std::string > &%s, " % (name))
+        else:
+            prototype.append("void %s, " % (name))
+    prototype.append(");\n")
+
+# starting from the end of string,
+# replace the first and 1-only comma by nothing
+#rreplace(prototype[tostring(), ',', '', 1)
+
+p = re.compile(", \);")
+prototypes = p.sub(");", ''.join(prototype))
+
+# FIXME relative path
+outfile = open(outputfile, "w")
+outfile.write(prototypes)
+outfile.close()
diff --git a/daemon/src/client/android/jni_callbacks.h b/daemon/src/client/android/jni_callbacks.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ce6e7bcb558b263da7357b44ea0f58bbda885c5
--- /dev/null
+++ b/daemon/src/client/android/jni_callbacks.h
@@ -0,0 +1,26 @@
+
+
+
+
+extern struct callmanager_callback wrapper_callback_struct;
+void on_new_call_created_wrapper (const std::string& accountID,
+                                         const std::string& callID,
+                                         const std::string& to);
+void on_call_state_changed_wrapper(const std::string& callID,
+                                          const std::string& to);
+void on_incoming_call_wrapper (const std::string& accountID,
+                                      const std::string& callID,
+                                      const std::string& from);
+void on_transfer_state_changed_wrapper (const std::string& result);
+
+void on_conference_created_wrapper (const std::string& confID);
+void on_conference_removed_wrapper (const std::string& confID);
+void on_conference_state_changed_wrapper(const std::string& confID,const std::string& state);
+void on_incoming_message_wrapper(const std::string& ID, const std::string& from, const std::string& msg);
+
+extern struct configurationmanager_callback wrapper_configurationcallback_struct;
+extern void on_accounts_changed_wrapper ();
+extern void on_account_state_changed_wrapper (const std::string& accoundID, int const& state);
+extern void on_account_state_changed_with_code_wrapper (const std::string& accoundID, const std::string& state, const int32_t& code);
+
+void on_record_playback_filepath_wrapper(const std::string& id, const std::string& filename);
diff --git a/daemon/src/client/android/jni_interface.i b/daemon/src/client/android/jni_interface.i
new file mode 100644
index 0000000000000000000000000000000000000000..3d98059825a857c95fde979cb04b9cdcc2a4743b
--- /dev/null
+++ b/daemon/src/client/android/jni_interface.i
@@ -0,0 +1,91 @@
+/*
+ *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ *  Author: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
+ *  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, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+/* File : jni_interface.i */
+%module (directors="1") SFLPhoneservice
+
+#define SWIG_JAVA_ATTACH_CURRENT_THREAD_AS_DAEMON
+%include "typemaps.i"
+%include "std_string.i" /* std::string typemaps */
+%include "enums.swg"
+%include "arrays_java.i";
+%include "carrays.i";
+%include "std_map.i";
+%include "std_vector.i";
+%include "stdint.i";
+
+/* void* shall be handled as byte arrays */
+%typemap(jni) void * "void *"
+%typemap(jtype) void * "byte[]"
+%typemap(jstype) void * "byte[]"
+%typemap(javain) void * "$javainput"
+%typemap(in) void * %{
+	$1 = $input;
+%}
+%typemap(javadirectorin) void * "$jniinput"
+%typemap(out) void * %{
+	$result = $1;
+%}
+%typemap(javaout) void * {
+	return $jnicall;
+}
+
+namespace std {
+    %template(StringMap) map<string, string>;
+    %template(StringVect) vector<string>;
+    %template(VectMap) vector< map<string,string> >;
+    %template(IntVect) vector<int32_t>;
+}
+
+/* not parsed by SWIG but needed by generated C files */
+%header %{
+
+#include <logger.h>
+
+%}
+
+%inline %{
+/* some functions that need to be declared in *_wrap.cpp
+ * that are not declared elsewhere in the c++ code
+ */
+%}
+
+/* parsed by SWIG to generate all the glue */
+/* %include "../managerimpl.h" */
+/* %include <dbus/callmanager.h> */
+
+//%constant struct callmanager_callback* WRAPPER_CALLBACK_STRUCT = &wrapper_callback_struct;
+
+%include "managerimpl.i"
+%include "callmanager.i"
+%include "configurationmanager.i"
+
+#ifndef SWIG
+/* some bad declarations */
+#endif
diff --git a/daemon/src/client/android/managerimpl.i b/daemon/src/client/android/managerimpl.i
new file mode 100644
index 0000000000000000000000000000000000000000..d86c546066019368b6488640b2deeb005dac1f79
--- /dev/null
+++ b/daemon/src/client/android/managerimpl.i
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ *  Author: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
+ *  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, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+/* %nodefaultctor ManagerImpl;
+%nodefaultdtor ManagerImpl; */
+%header %{
+#include <managerimpl.h>
+namespace Manager {
+extern ManagerImpl& instance();
+}
+%}
+
+class ManagerImpl {
+public:
+    void init(const std::string &config_file);
+    void setPath(const std::string &path);
+    bool outgoingCall(const std::string&, const std::string&, const std::string&, const std::string& = "");
+    void refuseCall(const std::string& id);
+    bool answerCall(const std::string& id);
+    void hangupCall(const std::string& id);
+};
+
+//%rename(Manager_instance) Manager::instance;
+
+namespace Manager {
+
+ManagerImpl& Manager::instance()
+{
+    // Meyers singleton
+    static ManagerImpl instance_;
+    return instance_;
+}
+
+}
diff --git a/daemon/src/client/android/sflphoneservice.c.template b/daemon/src/client/android/sflphoneservice.c.template
new file mode 100644
index 0000000000000000000000000000000000000000..916369e94b02197d3a9667ebee17ed6bf057ed9c
--- /dev/null
+++ b/daemon/src/client/android/sflphoneservice.c.template
@@ -0,0 +1,104 @@
+#include "logger.h"
+
+JavaVM *gJavaVM;
+const char *ksflphoneservicePath = "com/savoirfairelinux/sflphone/service/SFLPhoneserviceJNI";
+//const char *kManagerPath = "com/savoirfairelinux/sflphone/client/ManagerImpl";
+//static jobject gManagerObject, gDataObject;
+
+//void initClassHelper(JNIEnv *env, const char *path, jobject *objptr) {
+//    jclass cls;
+//
+//	INFO("initClassHelper");
+//
+//	cls= env->FindClass(path);
+//	if(!cls) {
+//        ERROR("initClassHelper: failed to get %s class reference", path);
+//        return;
+//    }
+//    jmethodID constr = env->GetMethodID(cls, "<init>", "()V");
+//	INFO("initClassHelper: %s method found", path);
+//
+//    if(!constr) {
+//        ERROR("initClassHelper: failed to get %s constructor", path);
+//        return;
+//    }
+//    jobject obj = env->NewObject(cls, constr);
+//	INFO("initClassHelper: %s constructor found", path);
+//
+//    if(!obj) {
+//        ERROR("initClassHelper: failed to create a %s object", path);
+//        return;
+//    }
+//	/* protect cached object instances from Android GC */
+//    (*objptr) = env->NewGlobalRef(obj);
+//	INFO("initClassHelper: object found %x", objptr);
+//}
+
+void deinitClassHelper(JNIEnv *env, jobject obj) {
+	INFO("deinitClassHelper");
+
+	/* delete cached object instances */
+    env->DeleteGlobalRef(obj);
+	INFO("deinitClassHelper: object %x deleted", obj);
+}
+
+JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+	JNIEnv *env;
+	jclass clazz;
+	jint r;
+
+    INFO("JNI_OnLoad");
+
+	//Assume it is c++
+	r = vm->GetEnv ((void **) &env, JNI_VERSION_1_6);
+    if (r != JNI_OK) {
+		ERROR("JNI_OnLoad: failed to get the environment using GetEnv()");
+        return -1;
+    }
+	INFO("JNI_Onload: GetEnv %p", env);
+
+	clazz = env->FindClass (ksflphoneservicePath);
+	if (!clazz) {
+        ERROR("JNI_Onload: whoops, %s class not found!", ksflphoneservicePath);
+	}
+	gJavaVM = vm;
+	INFO("JNI_Onload: JavaVM %p", gJavaVM);
+
+	/* put instances of class object we need into cache */
+    //initClassHelper(env, kManagerPath, &gManagerObject);
+
+	JNINativeMethod methods[] = {
+
+	$defs
+
+	};
+
+	r = env->RegisterNatives (clazz, methods, (int) (sizeof(methods) / sizeof(methods[0])));
+	return JNI_VERSION_1_6;
+}
+
+void JNI_OnUnLoad(JavaVM* vm, void* reserved) {
+    JNIEnv* env;
+	jclass clazz;
+
+	INFO("JNI_OnUnLoad");
+
+	/* get env */
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+		ERROR("JNI_OnUnLoad: failed to get the environment using GetEnv()");
+        return;
+    }
+	INFO("JNI_OnUnLoad: GetEnv %p", env);
+
+    /* Get jclass with env->FindClass */
+	clazz = env->FindClass(ksflphoneservicePath);
+	if (!clazz) {
+        ERROR("JNI_OnUnLoad: whoops, %s class not found!", ksflphoneservicePath);
+	}
+
+	/* remove instances of class object we need into cache */
+    //deinitClassHelper(env, gManagerObject);
+
+	env->UnregisterNatives(clazz);
+	INFO("JNI_OnUnLoad: Native functions unregistered");
+}
diff --git a/daemon/src/dbus/callmanager.h b/daemon/src/client/callmanager.h
similarity index 75%
rename from daemon/src/dbus/callmanager.h
rename to daemon/src/client/callmanager.h
index 043ebffecda02a05b1bb198fc3c443efcf155aeb..c2189a6dfe69b98afba904e2926d931d65bee2a3 100644
--- a/daemon/src/dbus/callmanager.h
+++ b/daemon/src/client/callmanager.h
@@ -31,7 +31,14 @@
 #ifndef __SFL_CALLMANAGER_H__
 #define __SFL_CALLMANAGER_H__
 
-#include "dbus_cpp.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if HAVE_DBUS
+
+#include "dbus/dbus_cpp.h"
+
 #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 6
 /* This warning option only exists for gcc 4.6.0 and greater. */
 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
@@ -39,7 +46,7 @@
 
 #pragma GCC diagnostic ignored "-Wignored-qualifiers"
 #pragma GCC diagnostic ignored "-Wunused-parameter"
-#include "callmanager-glue.h"
+#include "dbus/callmanager-glue.h"
 #pragma GCC diagnostic warning "-Wignored-qualifiers"
 #pragma GCC diagnostic warning "-Wunused-parameter"
 
@@ -48,25 +55,39 @@
 #pragma GCC diagnostic warning "-Wunused-but-set-variable"
 #endif
 
+#else
+// these includes normally come with DBus C++
+#include <vector>
+#include <map>
+#include <string>
+#endif  // HAVE_DBUS
+
 #include <stdexcept>
 
 class CallManagerException: public std::runtime_error {
     public:
-        CallManagerException(const std::string& str="") :
+        CallManagerException(const std::string& str = "") :
             std::runtime_error("A CallManagerException occured: " + str) {}
 };
 
 namespace sfl {
-    class AudioZrtpSession;
+class AudioZrtpSession;
 }
 
 class CallManager
+#if HAVE_DBUS
     : public org::sflphone::SFLphone::CallManager_adaptor,
   public DBus::IntrospectableAdaptor,
-      public DBus::ObjectAdaptor {
+  public DBus::ObjectAdaptor
+#endif
+{
     public:
 
+#if HAVE_DBUS
         CallManager(DBus::Connection& connection);
+#else
+        CallManager();
+#endif
 
         /* methods exported by this interface,
          * you will have to implement them in your ObjectAdaptor
@@ -86,8 +107,10 @@ class CallManager
         std::vector< std::string > getCallList();
 
         /* Conference related methods */
+        void removeConference(const std::string& conference_id);
         bool joinParticipant(const std::string& sel_callID, const std::string& drag_callID);
         void createConfFromParticipantList(const std::vector< std::string >& participants);
+        bool isConferenceParticipant(const std::string& call_id);
         bool addParticipant(const std::string& callID, const std::string& confID);
         bool addMainParticipant(const std::string& confID);
         bool detachParticipant(const std::string& callID);
@@ -126,6 +149,36 @@ class CallManager
 
         /* Instant messaging */
         void sendTextMessage(const std::string& callID, const std::string& message);
+        void sendTextMessage(const std::string& callID, const std::string& message, const std::string& from);
+
+#ifdef __ANDROID__
+        // signals must be implemented manually for Android
+        void callStateChanged(const std::string& callID, const std::string& state);
+
+        void transferFailed();
+
+        void transferSucceeded();
+
+        void recordPlaybackStopped(const std::string& path);
+
+        void voiceMailNotify(const std::string& callID, const std::string& nd_msg);
+
+        void incomingMessage(const std::string& ID, const std::string& from, const std::string& msg);
+
+        void incomingCall(const std::string& accountID, const std::string& callID, const std::string& from);
+
+        void recordPlaybackFilepath(const std::string& id, const std::string& filename);
+
+        void conferenceCreated(const std::string& confID);
+
+        void conferenceChanged(const std::string& confID,const std::string& state);
+
+        void updatePlaybackScale(const int32_t&, const int32_t&);
+        void conferenceRemoved(const std::string&);
+        void newCallCreated(const std::string&, const std::string&, const std::string&);
+        void registrationStateChanged(const std::string&, const std::string&, const int32_t&);
+        void sipCallStateChanged(const std::string&, const std::string&, const int32_t&);
+#endif // __ANDROID__
 
         /* Presence subscription */
         void subscribePresence(const std::string& accountID, const std::string& buddySipUri);
diff --git a/daemon/src/dbus/dbusmanager.h b/daemon/src/client/client.h
similarity index 90%
rename from daemon/src/dbus/dbusmanager.h
rename to daemon/src/client/client.h
index 99ac43b25b379fc62e6ceba8230f95f397ff5555..0ba877b1582baa48baa0965425755d1fb11316b8 100644
--- a/daemon/src/dbus/dbusmanager.h
+++ b/daemon/src/client/client.h
@@ -28,13 +28,12 @@
  *  as that of the covered work.
  */
 
-#ifndef __DBUSMANAGERIMPL_H__
-#define __DBUSMANAGERIMPL_H__
+#ifndef __CLIENT_H__
+#define __CLIENT_H__
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
-#include "dbus_cpp.h"
 #include "noncopyable.h"
 
 class ConfigurationManager;
@@ -43,10 +42,14 @@ class NetworkManager;
 class Instance;
 class VideoControls;
 
-class DBusManager {
+namespace DBus {
+    class BusDispatcher;
+}
+
+class Client {
     public:
-        DBusManager();
-        ~DBusManager();
+        Client();
+        ~Client();
 
         CallManager * getCallManager() {
             return callManager_;
@@ -60,15 +63,15 @@ class DBusManager {
         }
 #endif
 
-        void exec();
+        void event_loop();
         void exit();
 
     private:
-        NON_COPYABLE(DBusManager);
+        NON_COPYABLE(Client);
         CallManager*          callManager_;
         ConfigurationManager* configurationManager_;
         Instance*             instanceManager_;
-        DBus::BusDispatcher   dispatcher_;
+        DBus::BusDispatcher*  dispatcher_;
 #ifdef SFL_VIDEO
         VideoControls *videoControls_;
 #endif
diff --git a/daemon/src/dbus/configurationmanager.h b/daemon/src/client/configurationmanager.h
similarity index 89%
rename from daemon/src/dbus/configurationmanager.h
rename to daemon/src/client/configurationmanager.h
index 65277d3e797e37def86cc3878252866fe6fcde69..217b47610dd0939e1966583af7bafab362a1ff0d 100644
--- a/daemon/src/dbus/configurationmanager.h
+++ b/daemon/src/client/configurationmanager.h
@@ -34,6 +34,14 @@
 #ifndef CONFIGURATIONMANAGER_H
 #define CONFIGURATIONMANAGER_H
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if HAVE_DBUS
+
+#include "dbus/dbus_cpp.h"
+
 #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 6
 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #endif
@@ -41,7 +49,7 @@
 #pragma GCC diagnostic ignored "-Wignored-qualifiers"
 #pragma GCC diagnostic ignored "-Wunused-parameter"
 #pragma GCC diagnostic ignored "-Weffc++"
-#include "configurationmanager-glue.h"
+#include "dbus/configurationmanager-glue.h"
 #pragma GCC diagnostic warning "-Wignored-qualifiers"
 #pragma GCC diagnostic warning "-Wunused-parameter"
 #pragma GCC diagnostic warning "-Weffc++"
@@ -50,21 +58,31 @@
 #pragma GCC diagnostic warning "-Wunused-but-set-variable"
 #endif
 
-#include "dbus_cpp.h"
+#else
+// these includes normally come with DBus C++
+#include <vector>
+#include <map>
+#include <string>
+#endif // HAVE_DBUS
 
 class ConfigurationManager
+#if HAVE_DBUS
     : public org::sflphone::SFLphone::ConfigurationManager_adaptor,
     public DBus::IntrospectableAdaptor,
-    public DBus::ObjectAdaptor {
-
+    public DBus::ObjectAdaptor
+#endif
+{
     public:
+#if HAVE_DBUS
         ConfigurationManager(DBus::Connection& connection);
+#else
+        ConfigurationManager();
+#endif
         std::map< std::string, std::string > getAccountDetails(const std::string& accountID);
         void setAccountDetails(const std::string& accountID, const std::map< std::string, std::string >& details);
         std::map<std::string, std::string> getAccountTemplate();
         std::string addAccount(const std::map< std::string, std::string >& details);
         void removeAccount(const std::string& accoundID);
-        void deleteAllCredential(const std::string& accountID);
         std::vector< std::string > getAccountList();
         void sendRegister(const std::string& accoundID, const bool& enable);
         void registerAllAccounts(void);
@@ -129,7 +147,17 @@ class ConfigurationManager
 
         std::map<std::string, std::string> getShortcuts();
         void setShortcuts(const std::map<std::string, std::string> &shortcutsMap);
+
+#ifdef __ANDROID__
+        // signals must be implemented manually for Android
+        void accountsChanged();
+
+        void historyChanged();
+
+        void stunStatusFailure(const std::string& accoundID);
+
+        void registrationStateChanged(const std::string& accoundID, int const& state);
+#endif  // __ANDROID__
 };
 
 #endif //CONFIGURATIONMANAGER_H
-
diff --git a/daemon/src/dbus/Makefile.am b/daemon/src/client/dbus/Makefile.am
similarity index 82%
rename from daemon/src/dbus/Makefile.am
rename to daemon/src/client/dbus/Makefile.am
index 288f7287a5d7e2a84579acb597a210c839097808..bbd66cc08baa64fb865701ce79abc8d1453d3819 100644
--- a/daemon/src/dbus/Makefile.am
+++ b/daemon/src/client/dbus/Makefile.am
@@ -1,6 +1,6 @@
 include $(top_srcdir)/globals.mak
 
-noinst_LTLIBRARIES = libdbus.la
+noinst_LTLIBRARIES = libclient.la
 
 BUILT_SOURCES=                      \
     callmanager-glue.h              \
@@ -25,41 +25,41 @@ configurationmanager-glue.h: configurationmanager-introspec.xml Makefile.am
 instance-glue.h: instance-introspec.xml Makefile.am
 	dbusxx-xml2cpp $< --adaptor=$@
 
-libdbus_la_SOURCES = \
+libclient_la_SOURCES = \
     callmanager.cpp \
     configurationmanager.cpp  \
     instance.cpp  \
-    dbusmanager.cpp
+    client.cpp
 
 if SFL_VIDEO
-libdbus_la_SOURCES+=video_controls.cpp
+libclient_la_SOURCES+=video_controls.cpp
 endif
 
 if USE_NETWORKMANAGER
-libdbus_la_SOURCES += networkmanager.cpp
+libclient_la_SOURCES += networkmanager.cpp
 NETWORKMANAGER=-DUSE_NETWORKMANAGER
 else
 NETWORKMANAGER=
 endif
 
-libdbus_la_CXXFLAGS = \
+libclient_la_CXXFLAGS = -I../ \
             -DPREFIX=\"$(prefix)\" \
             -DPROGSHAREDIR=\"${datadir}/sflphone\" \
-            $(NETWORKMANAGER)
-
+            $(NETWORKMANAGER) \
+            $(DBUSCPP_CFLAGS)
 
 noinst_HEADERS =            \
-    callmanager.h           \
-    configurationmanager.h  \
+    ../callmanager.h        \
+    ../configurationmanager.h  \
     instance.h              \
-    dbusmanager.h           \
+    ../client.h             \
     networkmanager_proxy.h  \
     networkmanager.h        \
     dbus_cpp.h        		\
     $(BUILT_SOURCES)
 
 if SFL_VIDEO
-noinst_HEADERS+=video_controls.h
+noinst_HEADERS+=../video_controls.h
 endif
 
 # Dbus service file
diff --git a/daemon/src/dbus/README b/daemon/src/client/dbus/README
similarity index 57%
rename from daemon/src/dbus/README
rename to daemon/src/client/dbus/README
index 068ed5a7bfe34ec39addffb11e7510651c00b25b..45fdf4b41a5d66fa90282dadfaf4cce603e13eca 100644
--- a/daemon/src/dbus/README
+++ b/daemon/src/client/dbus/README
@@ -8,3 +8,17 @@ Examples:
 dbusxx-xml2cpp callmanager-introspec.xml --adaptor=callmanager-glue.h
 dbusxx-xml2cpp configurationmanager-introspec.xml --adaptor=configurationmanager-glue.h
 dbusxx-xml2cpp contactmanager-introspec.xml --adaptor=contactmanager-glue.h
+
+dbusxx-xml2cpp instance-introspec.xml --adaptor=instance-glue.h
+
+Warning : depending on the dbusxx-xml2cpp version used, it can generate buggy code
+
+code generated
+
+::DBus::IntrospectedInterface *const introspect() const
+
+instead of
+
+::DBus::IntrospectedInterface *introspect() const
+
+This issue is dealt with in make-swig.sh
diff --git a/daemon/src/dbus/callmanager-introspec.xml b/daemon/src/client/dbus/callmanager-introspec.xml
similarity index 99%
rename from daemon/src/dbus/callmanager-introspec.xml
rename to daemon/src/client/dbus/callmanager-introspec.xml
index 863a67e62628d24a1a447ddaafcac42e3b80c262..b0e9954dc0cadd00d811ebe09f9b07e5bdcffefd 100644
--- a/daemon/src/dbus/callmanager-introspec.xml
+++ b/daemon/src/client/dbus/callmanager-introspec.xml
@@ -211,6 +211,11 @@
             <arg type="as" name="participants" direction="in"/>
         </method>
 
+        <method name="isConferenceParticipant" tp:name-for-bindings="isConferenceParticipant">
+            <arg type="s" name="callID" direction="in"/>
+            <arg type="b" name="isParticipant" direction="out"/>
+        </method>
+
         <method name="addParticipant" tp:name-for-bindings="addParticipant">
             <tp:added version="0.9.7"/>
             <tp:docstring>
@@ -392,6 +397,7 @@
 
         <signal name="updatePlaybackScale" tp:name-for-bindings="updatePlaybackScale">
             <tp:docstring/>
+            <arg type="s" name="filepath" />
             <arg type="i" name="position" />
             <arg type="i" name="size" />
         </signal>
diff --git a/daemon/src/dbus/callmanager.cpp b/daemon/src/client/dbus/callmanager.cpp
similarity index 95%
rename from daemon/src/dbus/callmanager.cpp
rename to daemon/src/client/dbus/callmanager.cpp
index ceb92f5a90b3fe8897e96420465d32738e571661..3dc6e0757caef877bbf87049228ecb8237231852 100644
--- a/daemon/src/dbus/callmanager.cpp
+++ b/daemon/src/client/dbus/callmanager.cpp
@@ -160,6 +160,18 @@ CallManager::createConfFromParticipantList(const std::vector<std::string>& parti
     Manager::instance().createConfFromParticipantList(participants);
 }
 
+bool
+CallManager::isConferenceParticipant(const std::string& callID)
+{
+    return  Manager::instance().isConferenceParticipant(callID);
+}
+
+void
+CallManager::removeConference(const std::string& conference_id)
+{
+    Manager::instance().removeConference(conference_id);
+}
+
 bool
 CallManager::addParticipant(const std::string& callID, const std::string& confID)
 {
@@ -393,6 +405,13 @@ CallManager::acceptEnrollment(const std::string& callID, const bool& accepted)
 #endif
 }
 
+void CallManager::sendTextMessage(const std::string& callID, const std::string& message, const std::string& from)
+{
+#if HAVE_INSTANT_MESSAGING
+    Manager::instance().sendTextMessage(callID, message, from);
+#endif
+}
+
 void
 CallManager::sendTextMessage(const std::string& callID, const std::string& message)
 {
diff --git a/daemon/src/dbus/dbusmanager.cpp b/daemon/src/client/dbus/client.cpp
similarity index 91%
rename from daemon/src/dbus/dbusmanager.cpp
rename to daemon/src/client/dbus/client.cpp
index b9aa9a1fe9201b1973844d3ec08f373f32b2269d..fd069f3a09e3ab5d72b919f2fdde3621780360d2 100644
--- a/daemon/src/dbus/dbusmanager.cpp
+++ b/daemon/src/client/dbus/client.cpp
@@ -33,24 +33,26 @@
 #endif
 
 #include <cstdlib>
-#include "dbusmanager.h"
+#include "client/client.h"
 #include "global.h"
 #include "manager.h"
 #include "logger.h"
 #include "instance.h"
 
+#include "dbus_cpp.h"
+
 #include "callmanager.h"
 #include "configurationmanager.h"
 #include "networkmanager.h"
 
 #ifdef SFL_VIDEO
-#include "dbus/video_controls.h"
+#include "video_controls.h"
 #endif
 
-DBusManager::DBusManager() : callManager_(0)
+Client::Client() : callManager_(0)
     , configurationManager_(0)
     , instanceManager_(0)
-    , dispatcher_()
+    , dispatcher_(new DBus::BusDispatcher)
 #ifdef SFL_VIDEO
     , videoControls_(0)
 #endif
@@ -62,7 +64,7 @@ DBusManager::DBusManager() : callManager_(0)
         DEBUG("DBUS init threading");
         DBus::_init_threading();
         DEBUG("DBUS instantiate default dispatcher");
-        DBus::default_dispatcher = &dispatcher_;
+        DBus::default_dispatcher = dispatcher_;
 
         DEBUG("DBUS session connection to session bus");
         DBus::Connection sessionConnection(DBus::Connection::SessionBus());
@@ -93,9 +95,10 @@ DBusManager::DBusManager() : callManager_(0)
     }
 
     DEBUG("DBUS registration done");
+    instanceManager_->started();
 }
 
-DBusManager::~DBusManager()
+Client::~Client()
 {
 #ifdef USE_NETWORKMANAGER
     delete networkManager_;
@@ -106,12 +109,13 @@ DBusManager::~DBusManager()
     delete instanceManager_;
     delete configurationManager_;
     delete callManager_;
+    delete dispatcher_;
 }
 
-void DBusManager::exec()
+void Client::event_loop()
 {
     try {
-        dispatcher_.enter();
+        dispatcher_->enter();
     } catch (const DBus::Error &err) {
         ERROR("%s: %s, quitting\n", err.name(), err.what());
         return;
@@ -121,10 +125,10 @@ void DBusManager::exec()
     }
 }
 
-void DBusManager::exit()
+void Client::exit()
 {
     try {
-        dispatcher_.leave();
+        dispatcher_->leave();
     } catch (const DBus::Error &err) {
         ERROR("%s: %s, quitting\n", err.name(), err.what());
         return;
diff --git a/daemon/src/dbus/configurationmanager-introspec.xml b/daemon/src/client/dbus/configurationmanager-introspec.xml
similarity index 100%
rename from daemon/src/dbus/configurationmanager-introspec.xml
rename to daemon/src/client/dbus/configurationmanager-introspec.xml
diff --git a/daemon/src/dbus/configurationmanager.cpp b/daemon/src/client/dbus/configurationmanager.cpp
similarity index 100%
rename from daemon/src/dbus/configurationmanager.cpp
rename to daemon/src/client/dbus/configurationmanager.cpp
diff --git a/daemon/src/dbus/dbus_cpp.h b/daemon/src/client/dbus/dbus_cpp.h
similarity index 100%
rename from daemon/src/dbus/dbus_cpp.h
rename to daemon/src/client/dbus/dbus_cpp.h
diff --git a/daemon/src/dbus/instance-introspec.xml b/daemon/src/client/dbus/instance-introspec.xml
similarity index 88%
rename from daemon/src/dbus/instance-introspec.xml
rename to daemon/src/client/dbus/instance-introspec.xml
index f564d54cc1ed7bb941af0b35fb063928cd2a9f88..f3d1373a6409b7875a4d80db5bf0f815f285d637 100644
--- a/daemon/src/dbus/instance-introspec.xml
+++ b/daemon/src/client/dbus/instance-introspec.xml
@@ -29,5 +29,8 @@
 				</tp:docstring>
 			</arg>
 		</method>
+        <signal name="started" tp:name-for-bindings="started">
+            <tp:docstring>Notify clients that daemon has started</tp:docstring>
+        </signal>
     </interface>
 </node>
diff --git a/daemon/src/dbus/instance.cpp b/daemon/src/client/dbus/instance.cpp
similarity index 100%
rename from daemon/src/dbus/instance.cpp
rename to daemon/src/client/dbus/instance.cpp
diff --git a/daemon/src/dbus/instance.h b/daemon/src/client/dbus/instance.h
similarity index 100%
rename from daemon/src/dbus/instance.h
rename to daemon/src/client/dbus/instance.h
diff --git a/daemon/src/dbus/networkmanager.cpp b/daemon/src/client/dbus/networkmanager.cpp
similarity index 93%
rename from daemon/src/dbus/networkmanager.cpp
rename to daemon/src/client/dbus/networkmanager.cpp
index 063522b5f92ea9b56057637f911077d3c631f71e..5495525760b9cd69e831f59b5b06c381ad58c792 100644
--- a/daemon/src/dbus/networkmanager.cpp
+++ b/daemon/src/client/dbus/networkmanager.cpp
@@ -52,9 +52,8 @@ void NetworkManager::StateChanged(const uint32_t &state)
 void NetworkManager::PropertiesChanged(const std::map<std::string, ::DBus::Variant> &argin0)
 {
     WARN("Properties changed: ");
-    for (std::map<std::string, ::DBus::Variant>::const_iterator iter = argin0.begin();
-            iter != argin0.end(); ++iter)
-        WARN("%s", iter->first.c_str());
+    for (const auto &item : argin0)
+        WARN("%s", item.first.c_str());
     Manager::instance().registerAccounts();
 }
 
diff --git a/daemon/src/dbus/networkmanager.h b/daemon/src/client/dbus/networkmanager.h
similarity index 99%
rename from daemon/src/dbus/networkmanager.h
rename to daemon/src/client/dbus/networkmanager.h
index 86c6eb5628c55aa520e2abf40903235f5d9f2008..43803381a87d0138199f8c2a1ba1cb00a3f8efde 100644
--- a/daemon/src/dbus/networkmanager.h
+++ b/daemon/src/client/dbus/networkmanager.h
@@ -47,4 +47,3 @@ class NetworkManager : public org::freedesktop::NetworkManager_proxy,
         void PropertiesChanged(const std::map<std::string, ::DBus::Variant> &argin0);
 };
 #endif
-
diff --git a/daemon/src/dbus/networkmanager_proxy.h b/daemon/src/client/dbus/networkmanager_proxy.h
similarity index 100%
rename from daemon/src/dbus/networkmanager_proxy.h
rename to daemon/src/client/dbus/networkmanager_proxy.h
diff --git a/daemon/src/dbus/org.freedesktop.NetworkManager.xml b/daemon/src/client/dbus/org.freedesktop.NetworkManager.xml
similarity index 99%
rename from daemon/src/dbus/org.freedesktop.NetworkManager.xml
rename to daemon/src/client/dbus/org.freedesktop.NetworkManager.xml
index 591fb7b8edb61bbf3dd0ac5bdad85ae338fda3ee..a98db8123b27cca272b0fd2a46968160cbb52d06 100644
--- a/daemon/src/dbus/org.freedesktop.NetworkManager.xml
+++ b/daemon/src/client/dbus/org.freedesktop.NetworkManager.xml
@@ -13,4 +13,3 @@
     </signal>
   </interface>
 </node>
-
diff --git a/daemon/src/dbus/org.sflphone.SFLphone.service.in b/daemon/src/client/dbus/org.sflphone.SFLphone.service.in
similarity index 100%
rename from daemon/src/dbus/org.sflphone.SFLphone.service.in
rename to daemon/src/client/dbus/org.sflphone.SFLphone.service.in
diff --git a/daemon/src/dbus/video_controls-introspec.xml b/daemon/src/client/dbus/video_controls-introspec.xml
similarity index 100%
rename from daemon/src/dbus/video_controls-introspec.xml
rename to daemon/src/client/dbus/video_controls-introspec.xml
diff --git a/daemon/src/dbus/video_controls.cpp b/daemon/src/client/dbus/video_controls.cpp
similarity index 99%
rename from daemon/src/dbus/video_controls.cpp
rename to daemon/src/client/dbus/video_controls.cpp
index ad7126e8f4497dd1a230a41080465c3914861770..0220130bbdf20dff6f855985e847355030dacfb1 100644
--- a/daemon/src/dbus/video_controls.cpp
+++ b/daemon/src/client/dbus/video_controls.cpp
@@ -191,4 +191,3 @@ VideoControls::getCurrentCodecName(const std::string &callID)
 {
     return Manager::instance().getCurrentVideoCodecName(callID);
 }
-
diff --git a/daemon/src/dbus/video_controls.h b/daemon/src/client/video_controls.h
similarity index 96%
rename from daemon/src/dbus/video_controls.h
rename to daemon/src/client/video_controls.h
index 55f978cc456bb494a83fd2b6b51f672550be6c7c..fc25c570c8091e52e7d85b1dd64a18d4bdcf15ba 100644
--- a/daemon/src/dbus/video_controls.h
+++ b/daemon/src/client/video_controls.h
@@ -30,7 +30,13 @@
 #ifndef VIDEO_CONTROLS_H_
 #define VIDEO_CONTROLS_H_
 
-#include "dbus_cpp.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if HAVE_DBUS
+#include "dbus/dbus_cpp.h"
+
 #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 6
 /* This warning option only exists for gcc 4.6.0 and greater. */
 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
@@ -38,7 +44,7 @@
 
 #pragma GCC diagnostic ignored "-Wignored-qualifiers"
 #pragma GCC diagnostic ignored "-Wunused-parameter"
-#include "video_controls-glue.h"
+#include "dbus/video_controls-glue.h"
 #pragma GCC diagnostic warning "-Wignored-qualifiers"
 #pragma GCC diagnostic warning "-Wunused-parameter"
 
@@ -47,6 +53,7 @@
 #pragma GCC diagnostic warning "-Wunused-but-set-variable"
 #endif
 
+#endif // HAVE_DBUS
 
 #include <tr1/memory> // for shared_ptr
 #include "video/video_preferences.h"
@@ -122,4 +129,3 @@ class VideoControls : public org::sflphone::SFLphone::VideoControls_adaptor,
 };
 
 #endif // VIDEO_CONTROLS_H_
-
diff --git a/daemon/src/conference.cpp b/daemon/src/conference.cpp
index 1197d86af49f8d9f0ea487e1ce30ac2a9e2ffd21..f252f4589c064220c6c22b647ade1dbe1e4159ee 100644
--- a/daemon/src/conference.cpp
+++ b/daemon/src/conference.cpp
@@ -66,10 +66,9 @@ void Conference::remove(const std::string &participant_id)
 
 void Conference::bindParticipant(const std::string &participant_id)
 {
-    for (ParticipantSet::const_iterator iter = participants_.begin();
-            iter != participants_.end(); ++iter)
-        if (participant_id != *iter)
-            Manager::instance().getMainBuffer().bindCallID(participant_id, *iter);
+    for (const auto &item : participants_)
+        if (participant_id != item)
+            Manager::instance().getMainBuffer().bindCallID(participant_id, item);
 
     Manager::instance().getMainBuffer().bindCallID(participant_id, MainBuffer::DEFAULT_ID);
 }
@@ -108,15 +107,15 @@ bool Conference::toggleRecording()
 
     // start recording
     if (startRecording) {
-        for (ParticipantSet::const_iterator iter = participants_.begin(); iter != participants_.end(); ++iter)
-            mbuffer.bindHalfDuplexOut(process_id, *iter);
+        for (const auto &item : participants_)
+            mbuffer.bindHalfDuplexOut(process_id, item);
 
         mbuffer.bindHalfDuplexOut(process_id, MainBuffer::DEFAULT_ID);
 
         Recordable::recorder_.start();
     } else {
-        for (ParticipantSet::const_iterator iter = participants_.begin(); iter != participants_.end(); ++iter)
-            mbuffer.unBindHalfDuplexOut(process_id, *iter);
+        for (const auto &item : participants_)
+            mbuffer.unBindHalfDuplexOut(process_id, item);
 
         mbuffer.unBindHalfDuplexOut(process_id, MainBuffer::DEFAULT_ID);
     }
diff --git a/daemon/src/config/sfl_config.cpp b/daemon/src/config/sfl_config.cpp
index bff618cf4cae3b44626373ab939d64e95f7b608b..4fc4b186ecdee8d200eefbb96d591302a5a11c60 100644
--- a/daemon/src/config/sfl_config.cpp
+++ b/daemon/src/config/sfl_config.cpp
@@ -91,8 +91,8 @@ ConfigTree::getSections() const
 {
     std::list<std::string> sections;
 
-    for (SectionMap::const_iterator iter = sections_.begin(); iter != sections_.end(); ++iter)
-        sections.push_back(iter->first);
+    for (const auto &item : sections_)
+        sections.push_back(item.first);
 
     return sections;
 }
diff --git a/daemon/src/config/yamlemitter.cpp b/daemon/src/config/yamlemitter.cpp
index 2cd569139dce1191d4e8cbe5ed72693364008ca2..d3835c32e429a91a4c810de04fca9ebffd369625 100644
--- a/daemon/src/config/yamlemitter.cpp
+++ b/daemon/src/config/yamlemitter.cpp
@@ -144,8 +144,8 @@ void YamlEmitter::serializePreference(MappingNode *map, const char *preference_s
 
 void YamlEmitter::addMappingItems(int mappingID, YamlNodeMap &iMap)
 {
-    for (YamlNodeMap::const_iterator i = iMap.begin(); i != iMap.end(); ++i)
-        addMappingItem(mappingID, i->first, i->second);
+    for (const auto &i : iMap)
+        addMappingItem(mappingID, i.first, i.second);
 }
 
 void YamlEmitter::addMappingItem(int mappingid, const std::string &key, YamlNode *node)
@@ -195,8 +195,8 @@ void YamlEmitter::addMappingItem(int mappingid, const std::string &key, YamlNode
             throw YamlEmitterException("Could not append mapping pair to mapping");
 
         Sequence *seq = seqnode->getSequence();
-        for (Sequence::const_iterator it = seq->begin(); it != seq->end(); ++it) {
-            YamlNode *yamlNode = *it;
+        for (const auto &it : *seq) {
+            YamlNode *yamlNode = it;
             int id;
             if ((id = yaml_document_add_mapping(&document_, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0)
                 throw YamlEmitterException("Could not add account mapping to document");
diff --git a/daemon/src/config/yamlnode.cpp b/daemon/src/config/yamlnode.cpp
index 049129cbf6ccf0db1cbcd28fda5bfc770d95d556..214e04efb5002b620dd46129b153af202c09d72a 100644
--- a/daemon/src/config/yamlnode.cpp
+++ b/daemon/src/config/yamlnode.cpp
@@ -52,8 +52,8 @@ YamlNode *YamlDocument::popNode()
 
 void YamlDocument::deleteChildNodes()
 {
-    for (Sequence::iterator it = doc_.begin(); it != doc_.end(); ++it) {
-        YamlNode *yamlNode = static_cast<YamlNode *>(*it);
+    for (auto &it : doc_) {
+        YamlNode *yamlNode = static_cast<YamlNode *>(it);
 
         yamlNode->deleteChildNodes();
         delete yamlNode;
@@ -124,8 +124,8 @@ void MappingNode::getValue(const std::string &key, std::string *v) const
 
 void MappingNode::deleteChildNodes()
 {
-    for (YamlNodeMap::iterator it = map_.begin(); it != map_.end(); ++it) {
-        YamlNode *yamlNode = static_cast<YamlNode *>(it->second);
+    for (auto &it : map_) {
+        YamlNode *yamlNode = static_cast<YamlNode *>(it.second);
 
         if (!yamlNode)
             continue;
@@ -144,8 +144,8 @@ void SequenceNode::addNode(YamlNode *node)
 
 void SequenceNode::deleteChildNodes()
 {
-    for (Sequence::iterator it = seq_.begin(); it != seq_.end(); ++it) {
-        YamlNode *yamlNode = static_cast<YamlNode *>(*it);
+    for (auto &it : seq_) {
+        YamlNode *yamlNode = static_cast<YamlNode *>(it);
 
         yamlNode->deleteChildNodes();
         delete yamlNode;
diff --git a/daemon/src/config/yamlparser.cpp b/daemon/src/config/yamlparser.cpp
index 02cb3434ff659d4822d87c43720dc515fdcba04b..c720e45220ad9a43f701dfb9a3ea56f5d7a67c3a 100644
--- a/daemon/src/config/yamlparser.cpp
+++ b/daemon/src/config/yamlparser.cpp
@@ -380,8 +380,8 @@ void YamlParser::constructNativeData()
 {
     Sequence *seq = doc_.getSequence();
 
-    for (Sequence::iterator iter = seq->begin(); iter != seq->end(); ++iter) {
-        YamlNode *yamlNode = static_cast<YamlNode *>(*iter);
+    for (const auto &item : *seq) {
+        YamlNode *yamlNode = static_cast<YamlNode *>(item);
         if (yamlNode == NULL) {
             ERROR("Could not retrieve yaml node from document sequence");
             continue;
diff --git a/daemon/src/eventthread.cpp b/daemon/src/eventthread.cpp
index d4b833fc472c9b923d43c78855f2b92c1fd4bd5b..ee5c47c8089add0dfaa8e20e5372c39c0e5471bd 100644
--- a/daemon/src/eventthread.cpp
+++ b/daemon/src/eventthread.cpp
@@ -31,6 +31,11 @@
 #include "eventthread.h"
 #include "voiplink.h"
 
+ #ifdef __ANDROID__
+ #include <sched.h>
+ #define pthread_yield sched_yield
+ #endif
+
 EventThread::EventThread(VoIPLink *link) : link_(link), thread_(0)
 {}
 
diff --git a/daemon/src/fileutils.cpp b/daemon/src/fileutils.cpp
index 7a011388279571d5d13d8b2d1601bd04f684ba3a..a6f9f310d491b268a96a7d2ceaf4b1e7ddcabe60 100644
--- a/daemon/src/fileutils.cpp
+++ b/daemon/src/fileutils.cpp
@@ -71,7 +71,11 @@ bool check_dir(const char *path)
     return true;
 }
 
+#ifdef __ANDROID__
+static char *program_dir = "/data/data/com.savoirfairelinux.sflphone";
+#else
 static char *program_dir = NULL;
+#endif
 
 void set_program_dir(char *program_path)
 {
@@ -174,9 +178,14 @@ FileHandle::~FileHandle()
     }
 }
 
+
 std::string
 get_home_dir()
 {
+#ifdef __ANDROID__
+    return get_program_dir();
+#else
+
     // 1) try getting user's home directory from the environment
     const std::string home(PROTECTED_GETENV("HOME"));
     if (not home.empty())
@@ -192,5 +201,6 @@ get_home_dir()
     }
 
     return "";
+#endif
 }
 }
diff --git a/daemon/src/global.h b/daemon/src/global.h
index 98fc3ec4f740a63690f43bf8ae25e4d8b0415864..1c5e94679232ff9d951be4e715ca73608de58c00 100644
--- a/daemon/src/global.h
+++ b/daemon/src/global.h
@@ -33,8 +33,11 @@
 #ifndef __GLOBAL_H__
 #define __GLOBAL_H__
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <cstdio>
-#include <libintl.h>
 #include <locale.h>
 #include <string>
 #include <cstdlib>
@@ -42,8 +45,6 @@
 #include <map>
 #include <vector>
 
-#include "config.h"
-
 const char * const ZRTP_ZID_FILENAME = "sfl.zid";
 
 #define ALSA_DFT_CARD_ID 0          /** Index of the default soundcard */
diff --git a/daemon/src/history/history.cpp b/daemon/src/history/history.cpp
index b4c612ba49efa03044170aa86f7e0046f38e18b2..ad24587b8c958ed30bf04ca3691d775076072acc 100644
--- a/daemon/src/history/history.cpp
+++ b/daemon/src/history/history.cpp
@@ -36,6 +36,7 @@
 #include <fstream>
 #include <sys/stat.h> // for mkdir
 #include <ctime>
+#include <cstring>
 #include "scoped_lock.h"
 #include "fileutils.h"
 #include "logger.h"
@@ -43,6 +44,7 @@
 
 namespace sfl {
 
+
 using std::map;
 using std::string;
 using std::vector;
@@ -65,9 +67,12 @@ bool History::load(int limit)
         DEBUG("No history file to load");
         return false;
     }
-    while (!infile.eof()) {
+
+    int counter = 0;
+    while (!infile.eof() and counter < limit) {
         HistoryItem item(infile);
         addEntry(item, limit);
+        ++counter;
     }
     return true;
 }
@@ -81,9 +86,8 @@ bool History::save()
     std::ofstream outfile(path_.c_str());
     if (outfile.fail())
         return false;
-    for (vector<HistoryItem>::const_iterator iter = items_.begin();
-         iter != items_.end(); ++iter)
-        outfile << *iter << std::endl;
+    for (const auto &item : items_)
+        outfile << item << std::endl;
     return true;
 }
 
@@ -97,9 +101,11 @@ void History::addEntry(const HistoryItem &item, int oldest)
 void History::ensurePath()
 {
     if (path_.empty()) {
+#ifdef __ANDROID__
+		path_ = fileutils::get_home_dir() + DIR_SEPARATOR_STR "history";
+#else
         const string xdg_data = fileutils::get_home_dir() + DIR_SEPARATOR_STR +
                                 ".local/share/sflphone";
-
         // If the environment variable is set (not null and not empty), we'll use it to save the history
         // Else we 'll the standard one, ie: XDG_DATA_HOME = $HOME/.local/share/sflphone
         string xdg_env(XDG_DATA_HOME);
@@ -108,12 +114,13 @@ void History::ensurePath()
         if (mkdir(userdata.data(), 0755) != 0) {
             // If directory	creation failed
             if (errno != EEXIST) {
-                DEBUG("Cannot create directory: %m");
+                DEBUG("Cannot create directory: %s!: %s", userdata.c_str(), strerror(errno));
                 return;
             }
         }
         // Load user's history
         path_ = userdata + DIR_SEPARATOR_STR + "history";
+#endif
     }
 }
 
@@ -121,9 +128,8 @@ vector<map<string, string> > History::getSerialized()
 {
     sfl::ScopedLock lock(historyItemsMutex_);
     vector<map<string, string> > result;
-    for (vector<HistoryItem>::const_iterator iter = items_.begin();
-         iter != items_.end(); ++iter)
-        result.push_back(iter->toMap());
+    for (const auto &item : items_)
+        result.push_back(item.toMap());
 
     return result;
 }
diff --git a/daemon/src/history/history.h b/daemon/src/history/history.h
index 886cd40eebb5f7ecbf433fbc1cb393149b69475c..cac9b9b9ebfef299fcb3baef49f50c203e9cc093 100644
--- a/daemon/src/history/history.h
+++ b/daemon/src/history/history.h
@@ -66,11 +66,11 @@ class History {
 
         void addCall(Call *call, int limit);
         void clear();
+        void setPath(const std::string &path);
     private:
         /* Mutex to protect the history items */
         pthread_mutex_t historyItemsMutex_;
 
-        void setPath(const std::string &path);
         /* If no path has been set, this will initialize path to a
          * system-dependent location */
         void ensurePath();
diff --git a/daemon/src/history/historyitem.cpp b/daemon/src/history/historyitem.cpp
index ff09c0ea6c7f847c1e7843cd951cdf188f3f89f6..c7419e00f4217f022a4a640443003b8edaa3e5fa 100644
--- a/daemon/src/history/historyitem.cpp
+++ b/daemon/src/history/historyitem.cpp
@@ -103,13 +103,12 @@ bool HistoryItem::hasPeerNumber() const
 void HistoryItem::print(std::ostream &o) const
 {
     // every entry starts with "[" + random integer = "]"
-    for (map<string, string>::const_iterator iter = entryMap_.begin();
-         iter != entryMap_.end(); ++iter) {
+    for (const auto &item : entryMap_) {
         // if the file does not exist anymore, we do not save it
-        if (iter->first == RECORDING_PATH_KEY and not file_exists(iter->second))
-            o << iter->first << "=" << "" << std::endl;
+        if (item.first == RECORDING_PATH_KEY and not file_exists(item.second))
+            o << item.first << "=" << "" << std::endl;
         else
-            o << iter->first << "=" << iter->second << std::endl;
+            o << item.first << "=" << item.second << std::endl;
     }
 }
 
diff --git a/daemon/src/history/historynamecache.cpp b/daemon/src/history/historynamecache.cpp
index 24ec499da08fdedc5aa50626565c2cb7a451cf08..828448b28b79457c365cd35bf48d61c6f32a7aef 100644
--- a/daemon/src/history/historynamecache.cpp
+++ b/daemon/src/history/historynamecache.cpp
@@ -39,10 +39,10 @@ HistoryNameCache::HistoryNameCache() : hNameCache_()
 
     typedef vector<map<string, string> > HistoryList;
     HistoryList history(Manager::instance().getHistory());
-    for (HistoryList::iterator i = history.begin(); i != history.end(); ++i) {
-        string name((*i)["display_name"]);
-        string account((*i)["accountid"]);
-        string number((*i)["peer_number"]);
+    for (auto &i : history) {
+        string name(i["display_name"]);
+        string account(i["accountid"]);
+        string number(i["peer_number"]);
         if (hNameCache_[account][number].empty() and not name.empty() and not number.empty())
             hNameCache_[account][number] = name;
     }
diff --git a/daemon/src/iax/iaxaccount.cpp b/daemon/src/iax/iaxaccount.cpp
index 302d4502010d34b1d3142bf27c93e169eb19689c..06a934f3c8f3d922463feb83d1b558030b0bad1c 100644
--- a/daemon/src/iax/iaxaccount.cpp
+++ b/daemon/src/iax/iaxaccount.cpp
@@ -77,6 +77,9 @@ void IAXAccount::serialize(Conf::YamlEmitter &emitter)
     accountmap.setKeyValue(DISPLAY_NAME_KEY, &displayName);
     accountmap.setKeyValue(AUDIO_CODECS_KEY, &codecs);
 
+    Conf::ScalarNode userAgent(userAgent_);
+    accountmap.setKeyValue(USER_AGENT_KEY, &userAgent);
+
     try {
         emitter.serializeAccount(&accountmap);
     } catch (const Conf::YamlEmitterException &e) {
@@ -97,6 +100,8 @@ void IAXAccount::unserialize(const Conf::YamlNode &map)
     // Update codec list which one is used for SDP offer
     setActiveAudioCodecs(split_string(audioCodecStr_));
     map.getValue(DISPLAY_NAME_KEY, &displayName_);
+
+    map.getValue(USER_AGENT_KEY, &userAgent_);
 }
 
 void IAXAccount::setAccountDetails(std::map<std::string, std::string> details)
diff --git a/daemon/src/iax/iaxcall.cpp b/daemon/src/iax/iaxcall.cpp
index 934ab02a92cb5bba7015e0eda6a97364a90883d0..3c7c725bd222b52b51e6b806e290d3bec9099d88 100644
--- a/daemon/src/iax/iaxcall.cpp
+++ b/daemon/src/iax/iaxcall.cpp
@@ -74,8 +74,8 @@ int IAXCall::getSupportedFormat(const std::string &accountID) const
     if (account) {
         vector<int> codecs(account->getActiveAudioCodecs());
 
-        for (vector<int>::const_iterator i = codecs.begin(); i != codecs.end(); ++i)
-            format_mask |= codecToASTFormat(*i);
+        for (const auto &i : codecs)
+            format_mask |= codecToASTFormat(i);
     } else
         ERROR("No IAx account could be found");
 
@@ -90,8 +90,8 @@ int IAXCall::getFirstMatchingFormat(int needles, const std::string &accountID) c
     if (account != NULL) {
         vector<int> codecs(account->getActiveAudioCodecs());
 
-        for (vector<int>::const_iterator i = codecs.begin(); i != codecs.end(); ++i) {
-            int format_mask = codecToASTFormat(*i);
+        for (const auto &i : codecs) {
+            int format_mask = codecToASTFormat(i);
 
             // Return the first that matches
             if (format_mask & needles)
diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp
index 6ff8a6e2e7749a5f792bd3a5b1ddc5cdd0b38ae6..381df6eea64b61f36c1534fad929aa78af1a5d14 100644
--- a/daemon/src/iax/iaxvoiplink.cpp
+++ b/daemon/src/iax/iaxvoiplink.cpp
@@ -56,8 +56,8 @@ IAXVoIPLink::IAXVoIPLink(const std::string& accountID) :
     regSession_(NULL)
     , nextRefreshStamp_(0)
     , mutexIAX_()
-    , decData_()
-    , resampledData_()
+    , decData_(DEC_BUFFER_SIZE)
+    , resampledData_(DEC_BUFFER_SIZE*4)
     , encodedData_()
     , converter_(44100)
     , initDone_(false)
@@ -105,8 +105,8 @@ IAXVoIPLink::terminate()
 
     sfl::ScopedLock m(iaxCallMapMutex_);
 
-    for (IAXCallMap::iterator iter = iaxCallMap_.begin(); iter != iaxCallMap_.end(); ++iter) {
-        IAXCall *call = static_cast<IAXCall*>(iter->second);
+    for (auto &item : iaxCallMap_) {
+        IAXCall *call = static_cast<IAXCall*>(item.second);
 
         if (call) {
             sfl::ScopedLock lock(mutexIAX_);
@@ -182,8 +182,8 @@ IAXVoIPLink::getCallIDs()
 void
 IAXVoIPLink::sendAudioFromMic()
 {
-    for (IAXCallMap::const_iterator iter = iaxCallMap_.begin(); iter != iaxCallMap_.end() ; ++iter) {
-        IAXCall *currentCall = static_cast<IAXCall*>(iter->second);
+    for (const auto &item : iaxCallMap_) {
+        IAXCall *currentCall = static_cast<IAXCall*>(item.second);
 
         if (!currentCall or currentCall->getState() != Call::ACTIVE)
             continue;
@@ -200,33 +200,34 @@ IAXVoIPLink::sendAudioFromMic()
 
         // we have to get 20ms of data from the mic *20/1000 = /50
         // rate/50 shall be lower than IAX__20S_48KHZ_MAX
-        const size_t bytesNeeded = mainBufferSampleRate * 20 / 1000 * sizeof(SFLDataFormat);
+        size_t samples = mainBufferSampleRate * 20 / 1000;
 
-        if (Manager::instance().getMainBuffer().availableForGet(currentCall->getCallId()) < bytesNeeded)
+        if (Manager::instance().getMainBuffer().availableForGet(currentCall->getCallId()) < samples)
             continue;
 
         // Get bytes from micRingBuffer to data_from_mic
-        int bytes = Manager::instance().getMainBuffer().getData(decData_, bytesNeeded, currentCall->getCallId());
-        int samples = bytes / sizeof(SFLDataFormat);
+        decData_.resize(samples);
+        samples = Manager::instance().getMainBuffer().getData(decData_, currentCall->getCallId());
 
         int compSize;
         unsigned int audioRate = audioCodec->getClockRate();
         int outSamples;
-        SFLDataFormat *in;
+        AudioBuffer *in;
 
         if (audioRate != mainBufferSampleRate) {
-            converter_.resample(decData_, resampledData_, ARRAYSIZE(resampledData_),
-                                audioRate, mainBufferSampleRate, samples);
-            in = resampledData_;
+            decData_.setSampleRate(audioRate);
+            resampledData_.setSampleRate(mainBufferSampleRate);
+            converter_.resample(decData_, resampledData_);
+            in = &resampledData_;
             outSamples = 0;
         } else {
             outSamples = samples;
-            in = decData_;
+            in = &decData_;
         }
 
-        compSize = audioCodec->encode(encodedData_, in, DEC_BUFFER_SIZE);
+        compSize = audioCodec->encode(encodedData_, in->getData(), DEC_BUFFER_SIZE);
 
-        if (currentCall->session and bytes > 0) {
+        if (currentCall->session and samples > 0) {
             sfl::ScopedLock m(mutexIAX_);
 
             if (iax_send_voice(currentCall->session, currentCall->format, encodedData_, compSize, outSamples) == -1)
@@ -459,9 +460,8 @@ IAXVoIPLink::clearIaxCallMap()
 {
     sfl::ScopedLock m(iaxCallMapMutex_);
 
-    for (IAXCallMap::const_iterator iter = iaxCallMap_.begin();
-            iter != iaxCallMap_.end(); ++iter)
-        delete iter->second;
+    for (const auto &item : iaxCallMap_)
+        delete item.second;
 
     iaxCallMap_.clear();
 
@@ -539,8 +539,8 @@ IAXVoIPLink::iaxFindCallBySession(iax_session* session)
 {
     sfl::ScopedLock m(iaxCallMapMutex_);
 
-    for (IAXCallMap::const_iterator iter = iaxCallMap_.begin(); iter != iaxCallMap_.end(); ++iter) {
-        IAXCall* call = static_cast<IAXCall*>(iter->second);
+    for (const auto &item : iaxCallMap_) {
+        IAXCall* call = static_cast<IAXCall*>(item.second);
 
         if (call and call->session == session)
             return call;
@@ -660,19 +660,18 @@ void IAXVoIPLink::iaxHandleVoiceEvent(iax_event* event, IAXCall* call)
     if (size > max)
         size = max;
 
-    int samples = audioCodec->decode(decData_, data , size);
-    int outSize = samples * sizeof(SFLDataFormat);
-    SFLDataFormat *out = decData_;
+    audioCodec->decode(decData_.getData(), data , size);
+    AudioBuffer *out = &decData_;
     unsigned int audioRate = audioCodec->getClockRate();
 
     if (audioRate != mainBufferSampleRate) {
-        outSize = (double)outSize * (mainBufferSampleRate / audioRate);
-        converter_.resample(decData_, resampledData_, ARRAYSIZE(resampledData_),
-                            mainBufferSampleRate, audioRate, samples);
-        out = resampledData_;
+        decData_.setSampleRate(mainBufferSampleRate);
+        resampledData_.setSampleRate(audioRate);
+        converter_.resample(decData_, resampledData_);
+        out = &resampledData_;
     }
 
-    Manager::instance().getMainBuffer().putData(out, outSize, call->getCallId());
+    Manager::instance().getMainBuffer().putData(*out, call->getCallId());
 }
 
 /**
diff --git a/daemon/src/iax/iaxvoiplink.h b/daemon/src/iax/iaxvoiplink.h
index d6f9ba14d54565ef74c6e6a34dee08f535e89821..6de169ca7a3dc4f2a16a6425d48391adb5a78da3 100644
--- a/daemon/src/iax/iaxvoiplink.h
+++ b/daemon/src/iax/iaxvoiplink.h
@@ -39,6 +39,7 @@
 #include <pthread.h>
 #include "account.h"
 #include "voiplink.h"
+#include "audio/audiobuffer.h"
 #include "audio/codecs/audiocodec.h" // for DEC_BUFFER_SIZE
 #include "sfl_types.h"
 #include "noncopyable.h"
@@ -286,8 +287,10 @@ class IAXVoIPLink : public VoIPLink {
         pthread_mutex_t mutexIAX_;
 
         /** encoder/decoder/resampler buffers */
-        SFLDataFormat decData_[DEC_BUFFER_SIZE];
-        SFLDataFormat resampledData_[DEC_BUFFER_SIZE * 4];
+        AudioBuffer decData_;
+        AudioBuffer resampledData_;
+        //SFLAudioSample decData_[DEC_BUFFER_SIZE];
+        //SFLAudioSample resampledData_[DEC_BUFFER_SIZE * 4];
         unsigned char encodedData_[DEC_BUFFER_SIZE];
 
         /** Sample rate converter object */
diff --git a/daemon/src/im/instant_messaging.cpp b/daemon/src/im/instant_messaging.cpp
index c25490a5d330c01a57e03adf8e4fbbe0660003db..8e1e2c3ed5c5ecf075b722fc9021b3a0cb27c513 100644
--- a/daemon/src/im/instant_messaging.cpp
+++ b/daemon/src/im/instant_messaging.cpp
@@ -31,7 +31,7 @@
 
 #include "instant_messaging.h"
 #include "logger.h"
-#include "expat.h"
+#include <expat.h>
 
 namespace {
 void XMLCALL
@@ -99,20 +99,17 @@ void InstantMessaging::sip_send(pjsip_inv_session *session, const std::string& i
 void InstantMessaging::send_sip_message(pjsip_inv_session *session, const std::string &id, const std::string &message)
 {
     std::vector<std::string> msgs(split_message(message));
-    std::vector<std::string>::const_iterator iter;
-
-    for (iter = msgs.begin(); iter != msgs.end(); ++iter)
-        sip_send(session, id, *iter);
+    for (const auto &item : msgs)
+        sip_send(session, id, item);
 }
 
 #if HAVE_IAX
 void InstantMessaging::send_iax_message(iax_session *session, const std::string &/* id */, const std::string &message)
 {
     std::vector<std::string> msgs(split_message(message));
-    std::vector<std::string>::const_iterator iter;
 
-    for (iter = msgs.begin(); iter != msgs.end(); ++iter)
-        iax_send_text(session, (*iter).c_str());
+    for (const auto &item : msgs)
+        iax_send_text(session, item.c_str());
 }
 #endif
 
@@ -138,8 +135,8 @@ std::string InstantMessaging::generateXmlUriList(UriList &list)
                                   "<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\" xmlns:cp=\"urn:ietf:params:xml:ns:copycontrol\">"
                                   "<list>";
 
-    for (UriList::iterator iter = list.begin(); iter != list.end(); ++iter)
-        xmlbuffer += "<entry uri=" + (*iter)[sfl::IM_XML_URI] + " cp:copyControl=\"to\" />";
+    for (auto &item : list)
+        xmlbuffer += "<entry uri=" + item[sfl::IM_XML_URI] + " cp:copyControl=\"to\" />";
 
     return xmlbuffer + "</list></resource-lists>";
 }
diff --git a/daemon/src/im/instant_messaging.h b/daemon/src/im/instant_messaging.h
index f80113eebcd8246c12c94daa13536b737b940351..db01eeb718ffc66cb9a3bb17dbb4fbdb442f698f 100644
--- a/daemon/src/im/instant_messaging.h
+++ b/daemon/src/im/instant_messaging.h
@@ -45,10 +45,12 @@
 #include <list>
 #include <stdexcept>
 
-#include <iax-client.h>
-
 #include "config.h"
 
+#if HAVE_IAX
+#include <iax-client.h>
+#endif
+
 #define EMPTY_MESSAGE   pj_str((char*)"")
 #define MAXIMUM_MESSAGE_LENGTH		1560			/* PJSIP's sip message limit */
 
diff --git a/daemon/src/logger.h b/daemon/src/logger.h
index dd08deb6eafe1687524a3d5504e3e004d7e11682..95a1de47646dab69d3a21d7dc69563a2c21875c0 100644
--- a/daemon/src/logger.h
+++ b/daemon/src/logger.h
@@ -31,8 +31,13 @@
 #ifndef LOGGER_H_
 #define LOGGER_H_
 
-#include <syslog.h>
 #include <pthread.h>
+#ifdef __ANDROID__
+#include <cstring>
+#include <android/log.h>
+#else
+#include <syslog.h>
+#endif
 
 namespace Logger {
 void log(const int, const char*, ...);
@@ -42,13 +47,32 @@ void setDebugMode(bool);
 bool getDebugMode();
 };
 
-#define LOGGER(M, LEVEL, ...) Logger::log(LEVEL, "%s:%d:tid %lu:\t" M, __FILE__, \
-                                          __LINE__, pthread_self() & 0xffff, ##__VA_ARGS__)
+#define LOG_FORMAT(M, ...) "%s:%d:0x%x: " M, FILE_NAME, __LINE__, (unsigned long) pthread_self() & 0xffff, ##__VA_ARGS__
 
+#ifndef __ANDROID__
+
+#define FILE_NAME __FILE__
 #define ERROR(M, ...)   LOGGER(M, LOG_ERR, ##__VA_ARGS__)
 #define WARN(M, ...)    LOGGER(M, LOG_WARNING, ##__VA_ARGS__)
 #define INFO(M, ...)    LOGGER(M, LOG_INFO, ##__VA_ARGS__)
 #define DEBUG(M, ...)   LOGGER(M, LOG_DEBUG, ##__VA_ARGS__)
+#define LOGGER(M, LEVEL, ...) Logger::log(LEVEL, LOG_FORMAT(M, ##__VA_ARGS__))
+
+#else /* ANDROID */
+
+#ifndef APP_NAME
+#define APP_NAME "libsflphone"
+#endif
+
+// Avoid printing whole path on android
+#define FILE_NAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
+
+#define ERROR(M, ...)   LOGGER(M, ANDROID_LOG_ERROR, ##__VA_ARGS__)
+#define WARN(M, ...)    LOGGER(M, ANDROID_LOG_WARN, ##__VA_ARGS__)
+#define INFO(M, ...)    LOGGER(M, ANDROID_LOG_INFO, ##__VA_ARGS__)
+#define DEBUG(M, ...)   LOGGER(M, ANDROID_LOG_DEBUG, ##__VA_ARGS__)
+#define LOGGER(M, LEVEL, ...) __android_log_print(LEVEL, APP_NAME, LOG_FORMAT(M, ##__VA_ARGS__))
+#endif /* ANDROID */
 
 #define BLACK "\033[22;30m"
 #define RED "\033[22;31m"
diff --git a/daemon/src/main.cpp b/daemon/src/main.cpp
index 26095f95f72b89a80168820accb34d95ea1db360..ce1aae67bb55721b37fb036842911aa1bf64af43 100644
--- a/daemon/src/main.cpp
+++ b/daemon/src/main.cpp
@@ -35,6 +35,7 @@
 #endif
 
 #include <iostream>
+#include <signal.h>
 #include <getopt.h>
 #include "fileutils.h"
 #include "logger.h"
@@ -143,7 +144,7 @@ int main(int argc, char *argv [])
     std::vector<char> writable(programName.size() + 1);
     std::copy(programName.begin(), programName.end(), writable.begin());
 
-    fileutils::set_program_dir(&*writable.begin());
+    fileutils::set_program_dir(writable.data());
 
     print_title();
     if (parse_args(argc, argv))
@@ -170,8 +171,9 @@ int main(int argc, char *argv [])
 #ifdef SFL_VIDEO
     WARN("Built with video support");
 #endif
-
+#if HAVE_DBUS
     Manager::instance().run();
+#endif
     Manager::instance().saveHistory();
 
     return 0;
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index 858e45fbdbccfbc403cce54864dc678761daa71d..0570709039d7d68da815ffcc004ff9c4eea97fe4 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -40,7 +40,6 @@
 #include "managerimpl.h"
 #include "account_schema.h"
 
-#include "dbus/callmanager.h"
 #include "global.h"
 #include "fileutils.h"
 #include "map_utils.h"
@@ -59,16 +58,23 @@
 #include "numbercleaner.h"
 #include "config/yamlparser.h"
 #include "config/yamlemitter.h"
+
+#ifndef __ANDROID__
 #include "audio/alsa/alsalayer.h"
+#endif
+
 #include "audio/sound/tonelist.h"
 #include "audio/sound/audiofile.h"
 #include "audio/sound/dtmf.h"
 #include "history/historynamecache.h"
+#include "history/history.h"
 #include "manager.h"
 
-#include "dbus/configurationmanager.h"
+#include "client/configurationmanager.h"
+#include "client/callmanager.h"
+
 #ifdef SFL_VIDEO
-#include "dbus/video_controls.h"
+#include "client/video_controls.h"
 #endif
 
 #include "conference.h"
@@ -89,7 +95,7 @@
 ManagerImpl::ManagerImpl() :
     preferences(), voipPreferences(),
     hookPreference(),  audioPreference(), shortcutPreferences(),
-    hasTriedToRegister_(false), audioCodecFactory(), dbus_(), config_(),
+    hasTriedToRegister_(false), audioCodecFactory(), client_(), config_(),
     currentCallId_(), currentCallMutex_(), audiodriver_(0), dtmfKey_(),
     toneMutex_(), telephoneTone_(), audiofile_(), audioLayerMutex_(),
     waitingCalls_(), waitingCallsMutex_(), path_(),
@@ -113,29 +119,36 @@ ManagerImpl::~ManagerImpl()
 }
 
 namespace {
-    // Creates a backup of the file at "path" with a .bak suffix appended
-    void make_backup(const std::string &path)
+
+    void copy_over(const std::string &srcPath, const std::string &destPath)
     {
-        const std::string backup_path(path + ".bak");
-        std::ifstream src(path.c_str());
-        std::ofstream dest(backup_path.c_str());
+        std::ifstream src(srcPath.c_str());
+        std::ofstream dest(destPath.c_str());
         dest << src.rdbuf();
         src.close();
         dest.close();
     }
+    // Creates a backup of the file at "path" with a .bak suffix appended
+    void make_backup(const std::string &path)
+    {
+        const std::string backup_path(path + ".bak");
+        copy_over(path, backup_path);
+    }
+    // Restore last backup of the configuration file
+    void restore_backup(const std::string &path)
+    {
+        const std::string backup_path(path + ".bak");
+        copy_over(backup_path, path);
+    }
 }
 
-
-void ManagerImpl::init(const std::string &config_file)
+bool ManagerImpl::parseConfiguration()
 {
-    path_ = config_file.empty() ? createConfigFile() : config_file;
-    DEBUG("Configuration file path: %s", path_.c_str());
+    bool result = true;
 
-    bool no_errors = true;
+    FILE *file = fopen(path_.c_str(), "rb");
 
     try {
-        FILE *file = fopen(path_.c_str(), "rb");
-
         if (file) {
             Conf::YamlParser parser(file);
             parser.serializeEvents();
@@ -145,20 +158,50 @@ void ManagerImpl::init(const std::string &config_file)
             fclose(file);
             if (error_count > 0) {
                 WARN("Errors while parsing %s", path_.c_str());
-                no_errors = false;
+                result = false;
             }
         } else {
             WARN("Config file not found: creating default account map");
             loadDefaultAccountMap();
         }
+    } catch (const Conf::YamlParserException &e) {
+        // we only want to close the local file here and then rethrow the exception
+        fclose(file);
+        throw;
+    }
+
+    return result;
+}
+
+void ManagerImpl::init(const std::string &config_file)
+{
+    path_ = config_file.empty() ? retrieveConfigPath() : config_file;
+    DEBUG("Configuration file path: %s", path_.c_str());
+
+    bool no_errors = true;
+
+    try {
+        no_errors = parseConfiguration();
     } catch (const Conf::YamlParserException &e) {
         ERROR("%s", e.what());
         no_errors = false;
     }
 
     // always back up last error-free configuration
-    if (no_errors)
+    if (no_errors) {
         make_backup(path_);
+    } else {
+        // restore previous configuration
+        WARN("Restoring last working configuration");
+        try {
+            restore_backup(path_);
+            parseConfiguration();
+        } catch (const Conf::YamlParserException &e) {
+            ERROR("%s", e.what());
+            WARN("Restoring backup failed, creating default account map");
+            loadDefaultAccountMap();
+        }
+    }
 
     initAudioDriver();
 
@@ -177,11 +220,17 @@ void ManagerImpl::init(const std::string &config_file)
     registerAccounts();
 }
 
+void ManagerImpl::setPath(const std::string &path) {
+	history_.setPath(path);
+}
+
+#if HAVE_DBUS
 void ManagerImpl::run()
 {
-    DEBUG("Starting DBus event loop");
-    dbus_.exec();
+    DEBUG("Starting client event loop");
+    client_.event_loop();
 }
+#endif
 
 void ManagerImpl::finish()
 {
@@ -197,9 +246,8 @@ void ManagerImpl::finish()
     std::vector<std::string> callList(getCallList());
     DEBUG("Hangup %zu remaining call(s)", callList.size());
 
-    for (std::vector<std::string>::iterator iter = callList.begin();
-            iter != callList.end(); ++iter)
-        hangupCall(*iter);
+    for (const auto &item : callList)
+        hangupCall(item);
 
     saveConfig();
 
@@ -217,7 +265,7 @@ void ManagerImpl::finish()
         audiodriver_ = NULL;
     }
 
-    dbus_.exit();
+    client_.exit();
 }
 
 bool ManagerImpl::isCurrentCall(const std::string& callId) const
@@ -343,8 +391,7 @@ bool ManagerImpl::answerCall(const std::string& call_id)
     stopTone();
 
     // set playback mode to VOICE
-    AudioLayer *al = getAudioDriver();
-    if(al) al->setPlaybackMode(AudioLayer::VOICE);
+    if (audiodriver_) audiodriver_->setPlaybackMode(AudioLayer::VOICE);
 
     // store the current call id
     std::string current_call_id(getCurrentCallId());
@@ -391,8 +438,8 @@ bool ManagerImpl::answerCall(const std::string& call_id)
     if (audioPreference.getIsAlwaysRecording())
         toggleRecordingCall(call_id);
 
-    // update call state on client side
-    dbus_.getCallManager()->callStateChanged(call_id, "CURRENT");
+    client_.getCallManager()->callStateChanged(call_id, "CURRENT");
+
     return result;
 }
 
@@ -403,6 +450,7 @@ void ManagerImpl::checkAudio()
         if (audiodriver_)
             audiodriver_->stopStream();
     }
+
 }
 
 //THREAD=Main
@@ -414,12 +462,10 @@ bool ManagerImpl::hangupCall(const std::string& callId)
     stopTone();
 
     // set playback mode to NONE
-    AudioLayer *al = getAudioDriver();
-    if(al) al->setPlaybackMode(AudioLayer::NONE);
+    if (audiodriver_) audiodriver_->setPlaybackMode(AudioLayer::NONE);
 
-    /* Broadcast a signal over DBus */
-    DEBUG("Send DBUS call state change (HUNGUP) for id %s", callId.c_str());
-    dbus_.getCallManager()->callStateChanged(callId, "HUNGUP");
+    DEBUG("Send call state change (HUNGUP) for id %s", callId.c_str());
+    client_.getCallManager()->callStateChanged(callId, "HUNGUP");
 
     /* We often get here when the call was hungup before being created */
     if (not isValidCall(callId) and not isIPToIP(callId)) {
@@ -480,9 +526,8 @@ bool ManagerImpl::hangupConference(const std::string& id)
         if (conf) {
             ParticipantSet participants(conf->getParticipantList());
 
-            for (ParticipantSet::const_iterator iter = participants.begin();
-                    iter != participants.end(); ++iter)
-                hangupCall(*iter);
+            for (const auto &item : participants)
+                hangupCall(item);
         } else {
             ERROR("No such conference %s", id.c_str());
             return false;
@@ -536,7 +581,7 @@ bool ManagerImpl::onHoldCall(const std::string& callId)
     if (current_call_id == callId)
         unsetCurrentCall();
 
-    dbus_.getCallManager()->callStateChanged(callId, "HOLD");
+    client_.getCallManager()->callStateChanged(callId, "HOLD");
 
     getMainBuffer().dumpInfo();
     return result;
@@ -574,7 +619,7 @@ bool ManagerImpl::offHoldCall(const std::string& callId)
             result = false;
     }
 
-    dbus_.getCallManager()->callStateChanged(callId, "UNHOLD");
+    client_.getCallManager()->callStateChanged(callId, "UNHOLD");
 
     if (isConferenceParticipant(callId)) {
         Call *call = getCallFromCallID(callId);
@@ -622,12 +667,12 @@ bool ManagerImpl::transferCall(const std::string& callId, const std::string& to)
 
 void ManagerImpl::transferFailed()
 {
-    dbus_.getCallManager()->transferFailed();
+    client_.getCallManager()->transferFailed();
 }
 
 void ManagerImpl::transferSucceeded()
 {
-    dbus_.getCallManager()->transferSucceeded();
+    client_.getCallManager()->transferSucceeded();
 }
 
 bool ManagerImpl::attendedTransfer(const std::string& transferID, const std::string& targetID)
@@ -674,7 +719,8 @@ bool ManagerImpl::refuseCall(const std::string& id)
     }
 
     removeWaitingCall(id);
-    dbus_.getCallManager()->callStateChanged(id, "HUNGUP");
+
+    client_.getCallManager()->callStateChanged(id, "HUNGUP");
 
     // Disconnect streams
     removeStream(id);
@@ -696,8 +742,7 @@ ManagerImpl::createConference(const std::string& id1, const std::string& id2)
     // Add conference to map
     conferenceMap_.insert(std::make_pair(conf->getConfID(), conf));
 
-    // broadcast a signal over dbus
-    dbus_.getCallManager()->conferenceCreated(conf->getConfID());
+    client_.getCallManager()->conferenceCreated(conf->getConfID());
 
     return conf;
 }
@@ -718,8 +763,7 @@ void ManagerImpl::removeConference(const std::string& conference_id)
         return;
     }
 
-    // broadcast a signal over dbus
-    dbus_.getCallManager()->conferenceRemoved(conference_id);
+    client_.getCallManager()->conferenceRemoved(conference_id);
 
     // We now need to bind the audio to the remain participant
 
@@ -774,14 +818,15 @@ ManagerImpl::holdConference(const std::string& id)
 
     ParticipantSet participants(conf->getParticipantList());
 
-    for (ParticipantSet::const_iterator iter = participants.begin();
-            iter != participants.end(); ++iter) {
-        switchCall(*iter);
-        onHoldCall(*iter);
+    for (const auto &item : participants) {
+        switchCall(item);
+        onHoldCall(item);
     }
 
     conf->setState(isRec ? Conference::HOLD_REC : Conference::HOLD);
-    dbus_.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr());
+
+    client_.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr());
+
     return true;
 }
 
@@ -801,19 +846,21 @@ ManagerImpl::unHoldConference(const std::string& id)
 
     ParticipantSet participants(conf->getParticipantList());
 
-    for (ParticipantSet::const_iterator iter = participants.begin(); iter!= participants.end(); ++iter) {
-        Call *call = getCallFromCallID(*iter);
+    for (const auto &item : participants) {
+        Call *call = getCallFromCallID(item);
         if (call) {
             // if one call is currently recording, the conference is in state recording
             isRec |= call->isRecording();
 
-            switchCall(*iter);
-            offHoldCall(*iter);
+            switchCall(item);
+            offHoldCall(item);
         }
     }
 
     conf->setState(isRec ? Conference::ACTIVE_ATTACHED_REC : Conference::ACTIVE_ATTACHED);
-    dbus_.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr());
+
+    client_.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr());
+
     return true;
 }
 
@@ -897,9 +944,8 @@ ManagerImpl::addParticipant(const std::string& callId, const std::string& confer
 
     // reset ring buffer for all conference participant
     // flush conference participants only
-    for (ParticipantSet::const_iterator p = participants.begin();
-            p != participants.end(); ++p)
-        getMainBuffer().flush(*p);
+    for (const auto &p : participants)
+        getMainBuffer().flush(p);
 
     getMainBuffer().flush(MainBuffer::DEFAULT_ID);
 
@@ -932,11 +978,10 @@ ManagerImpl::addMainParticipant(const std::string& conference_id)
 
         ParticipantSet participants(conf->getParticipantList());
 
-        for (ParticipantSet::const_iterator iter_p = participants.begin();
-                iter_p != participants.end(); ++iter_p) {
-            getMainBuffer().bindCallID(*iter_p, MainBuffer::DEFAULT_ID);
+        for (const auto &item_p : participants) {
+            getMainBuffer().bindCallID(item_p, MainBuffer::DEFAULT_ID);
             // Reset ringbuffer's readpointers
-            getMainBuffer().flush(*iter_p);
+            getMainBuffer().flush(item_p);
         }
 
         getMainBuffer().flush(MainBuffer::DEFAULT_ID);
@@ -948,7 +993,7 @@ ManagerImpl::addMainParticipant(const std::string& conference_id)
         else
             WARN("Invalid conference state while adding main participant");
 
-        dbus_.getCallManager()->conferenceChanged(conference_id, conf->getStateStr());
+        client_.getCallManager()->conferenceChanged(conference_id, conf->getStateStr());
     }
 
     switchCall(conference_id);
@@ -1088,9 +1133,8 @@ void ManagerImpl::createConfFromParticipantList(const std::vector< std::string >
 
     int successCounter = 0;
 
-    for (std::vector<std::string>::const_iterator p = participantList.begin();
-         p != participantList.end(); ++p) {
-        std::string numberaccount(*p);
+    for (const auto &p : participantList) {
+        std::string numberaccount(p);
         std::string tostr(numberaccount.substr(0, numberaccount.find(",")));
         std::string account(numberaccount.substr(numberaccount.find(",") + 1, numberaccount.size()));
 
@@ -1108,7 +1152,7 @@ void ManagerImpl::createConfFromParticipantList(const std::vector< std::string >
         if (!callSuccess)
             conf->remove(generatedCallID);
         else {
-            dbus_.getCallManager()->newCallCreated(account, generatedCallID, tostr);
+            client_.getCallManager()->newCallCreated(account, generatedCallID, tostr);
             successCounter++;
         }
     }
@@ -1116,7 +1160,7 @@ void ManagerImpl::createConfFromParticipantList(const std::vector< std::string >
     // Create the conference if and only if at least 2 calls have been successfully created
     if (successCounter >= 2) {
         conferenceMap_[conf->getConfID()] = conf;
-        dbus_.getCallManager()->conferenceCreated(conf->getConfID());
+        client_.getCallManager()->conferenceCreated(conf->getConfID());
 
         {
             sfl::ScopedLock lock(audioLayerMutex_);
@@ -1189,7 +1233,7 @@ ManagerImpl::detachParticipant(const std::string& call_id)
         else
             WARN("Undefined behavior, invalid conference state in detach participant");
 
-        dbus_.getCallManager()->conferenceChanged(conf->getConfID(),
+        client_.getCallManager()->conferenceChanged(conf->getConfID(),
                                                   conf->getStateStr());
 
         unsetCurrentCall();
@@ -1221,8 +1265,11 @@ void ManagerImpl::removeParticipant(const std::string& call_id)
     call->setConfId("");
 
     removeStream(call_id);
+
     getMainBuffer().dumpInfo();
-    dbus_.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr());
+
+    client_.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr());
+
     processRemainingParticipants(*conf);
 }
 
@@ -1236,9 +1283,8 @@ void ManagerImpl::processRemainingParticipants(Conference &conf)
 
     if (n > 1) {
         // Reset ringbuffer's readpointers
-        for (ParticipantSet::const_iterator p = participants.begin();
-             p != participants.end(); ++p)
-            getMainBuffer().flush(*p);
+        for (const auto &p : participants)
+            getMainBuffer().flush(p);
 
         getMainBuffer().flush(MainBuffer::DEFAULT_ID);
     } else if (n == 1) {
@@ -1282,9 +1328,8 @@ ManagerImpl::joinConference(const std::string& conf_id1,
     Conference *conf = conferenceMap_.find(conf_id1)->second;
     ParticipantSet participants(conf->getParticipantList());
 
-    for (ParticipantSet::const_iterator p = participants.begin();
-            p != participants.end(); ++p)
-        addParticipant(*p, conf_id2);
+    for (const auto &p : participants)
+        addParticipant(p, conf_id2);
 
     return true;
 }
@@ -1308,9 +1353,8 @@ void ManagerImpl::addStream(const std::string& call_id)
             ParticipantSet participants(conf->getParticipantList());
 
             // reset ring buffer for all conference participant
-            for (ParticipantSet::const_iterator iter_p = participants.begin();
-                    iter_p != participants.end(); ++iter_p)
-                getMainBuffer().flush(*iter_p);
+            for (const auto &participant : participants)
+                getMainBuffer().flush(participant);
 
             getMainBuffer().flush(MainBuffer::DEFAULT_ID);
         }
@@ -1340,22 +1384,20 @@ void ManagerImpl::removeStream(const std::string& call_id)
 void ManagerImpl::saveConfig()
 {
     DEBUG("Saving Configuration to XDG directory %s", path_.c_str());
-    AudioLayer *audiolayer = getAudioDriver();
-    if (audiolayer != NULL) {
-        audioPreference.setVolumemic(audiolayer->getCaptureGain());
-        audioPreference.setVolumespkr(audiolayer->getPlaybackGain());
+    if (audiodriver_ != NULL) {
+        audioPreference.setVolumemic(audiodriver_->getCaptureGain());
+        audioPreference.setVolumespkr(audiodriver_->getPlaybackGain());
     }
 
     try {
         Conf::YamlEmitter emitter(path_.c_str());
 
-        for (AccountMap::iterator iter = SIPVoIPLink::instance()->getAccounts().begin();
-             iter != SIPVoIPLink::instance()->getAccounts().end(); ++iter)
-            iter->second->serialize(emitter);
+        for (auto &item : SIPVoIPLink::instance()->getAccounts())
+            item.second->serialize(emitter);
 
 #if HAVE_IAX
-        for (AccountMap::iterator iter = IAXVoIPLink::getAccounts().begin(); iter != IAXVoIPLink::getAccounts().end(); ++iter)
-            iter->second->serialize(emitter);
+        for (auto &item : IAXVoIPLink::getAccounts())
+            item.second->serialize(emitter);
 #endif
 
         preferences.serialize(emitter);
@@ -1423,19 +1465,20 @@ void ManagerImpl::playDtmf(char code)
 
     // this buffer is for mono
     // TODO <-- this should be global and hide if same size
-    std::vector<SFLDataFormat> buf(size);
+    //std::vector<SFLAudioSample> buf(size);
+    AudioBuffer buf(size);
 
     // Handle dtmf
     dtmfKey_->startTone(code);
 
     // copy the sound
-    if (dtmfKey_->generateDTMF(buf)) {
+    if (dtmfKey_->generateDTMF(*buf.getChannel(0))) {
         // Put buffer to urgentRingBuffer
         // put the size in bytes...
         // so size * 1 channel (mono) * sizeof (bytes for the data)
         // audiolayer->flushUrgent();
         audiodriver_->startStream();
-        audiodriver_->putUrgent(&(*buf.begin()), size * sizeof(SFLDataFormat));
+        audiodriver_->putUrgent(buf);
     }
 
     // TODO Cache the DTMF
@@ -1485,7 +1528,7 @@ void ManagerImpl::incomingCall(Call &call, const std::string& accountId)
 
     if (not hasCurrentCall()) {
         call.setConnectionState(Call::RINGING);
-        ringtone(accountId);
+        playRingtone(accountId);
     }
 
     addWaitingCall(callID);
@@ -1493,7 +1536,8 @@ void ManagerImpl::incomingCall(Call &call, const std::string& accountId)
     std::string number(call.getPeerNumber());
 
     std::string from("<" + number + ">");
-    dbus_.getCallManager()->incomingCall(accountId, callID, call.getDisplayName() + " " + from);
+
+    client_.getCallManager()->incomingCall(accountId, callID, call.getDisplayName() + " " + from);
 }
 
 
@@ -1508,15 +1552,14 @@ void ManagerImpl::incomingMessage(const std::string& callID,
 
         ParticipantSet participants(conf->getParticipantList());
 
-        for (ParticipantSet::const_iterator iter_p = participants.begin();
-                iter_p != participants.end(); ++iter_p) {
+        for (const auto &item_p : participants) {
 
-            if (*iter_p == callID)
+            if (item_p == callID)
                 continue;
 
-            std::string accountId(getAccountFromCall(*iter_p));
+            std::string accountId(getAccountFromCall(item_p));
 
-            DEBUG("Send message to %s, (%s)", (*iter_p).c_str(), accountId.c_str());
+            DEBUG("Send message to %s, (%s)", item_p.c_str(), accountId.c_str());
 
             Account *account = getAccount(accountId);
 
@@ -1529,10 +1572,10 @@ void ManagerImpl::incomingMessage(const std::string& callID,
         }
 
         // in case of a conference we must notify client using conference id
-        dbus_.getCallManager()->incomingMessage(conf->getConfID(), from, message);
+        client_.getCallManager()->incomingMessage(conf->getConfID(), from, message);
 
     } else
-        dbus_.getCallManager()->incomingMessage(callID, from, message);
+        client_.getCallManager()->incomingMessage(callID, from, message);
 }
 
 //THREAD=VoIP
@@ -1552,10 +1595,9 @@ bool ManagerImpl::sendTextMessage(const std::string& callID, const std::string&
 
         ParticipantSet participants(conf->getParticipantList());
 
-        for (ParticipantSet::const_iterator iter_p = participants.begin();
-                iter_p != participants.end(); ++iter_p) {
+        for (const auto &participant : participants) {
 
-            std::string accountId = getAccountFromCall(*iter_p);
+            std::string accountId = getAccountFromCall(participant);
 
             Account *account = getAccount(accountId);
 
@@ -1564,7 +1606,7 @@ bool ManagerImpl::sendTextMessage(const std::string& callID, const std::string&
                 return false;
             }
 
-            account->getVoIPLink()->sendTextMessage(*iter_p, message, from);
+            account->getVoIPLink()->sendTextMessage(participant, message, from);
         }
 
         return true;
@@ -1579,10 +1621,9 @@ bool ManagerImpl::sendTextMessage(const std::string& callID, const std::string&
 
         ParticipantSet participants(conf->getParticipantList());
 
-        for (ParticipantSet::const_iterator iter_p = participants.begin();
-                iter_p != participants.end(); ++iter_p) {
+        for (const auto &item_p : participants) {
 
-            const std::string accountId(getAccountFromCall(*iter_p));
+            const std::string accountId(getAccountFromCall(item_p));
 
             Account *account = getAccount(accountId);
 
@@ -1591,7 +1632,7 @@ bool ManagerImpl::sendTextMessage(const std::string& callID, const std::string&
                 return false;
             }
 
-            account->getVoIPLink()->sendTextMessage(*iter_p, message, from);
+            account->getVoIPLink()->sendTextMessage(item_p, message, from);
         }
     } else {
         Account *account = getAccount(getAccountFromCall(callID));
@@ -1617,8 +1658,7 @@ void ManagerImpl::peerAnsweredCall(const std::string& id)
         stopTone();
 
         // set playback mode to VOICE
-        AudioLayer *al = getAudioDriver();
-        if(al) al->setPlaybackMode(AudioLayer::VOICE);
+        if (audiodriver_) audiodriver_->setPlaybackMode(AudioLayer::VOICE);
     }
 
     // Connect audio streams
@@ -1633,7 +1673,7 @@ void ManagerImpl::peerAnsweredCall(const std::string& id)
     if (audioPreference.getIsAlwaysRecording())
         toggleRecordingCall(id);
 
-    dbus_.getCallManager()->callStateChanged(id, "CURRENT");
+    client_.getCallManager()->callStateChanged(id, "CURRENT");
 }
 
 //THREAD=VoIP Call=Outgoing
@@ -1644,7 +1684,7 @@ void ManagerImpl::peerRingingCall(const std::string& id)
     if (isCurrentCall(id))
         ringback();
 
-    dbus_.getCallManager()->callStateChanged(id, "RINGING");
+    client_.getCallManager()->callStateChanged(id, "RINGING");
 }
 
 //THREAD=VoIP Call=Outgoing/Ingoing
@@ -1659,8 +1699,7 @@ void ManagerImpl::peerHungupCall(const std::string& call_id)
         unsetCurrentCall();
 
         // set playback mode to NONE
-        AudioLayer *al = getAudioDriver();
-        if(al) al->setPlaybackMode(AudioLayer::NONE);
+        if (audiodriver_) audiodriver_->setPlaybackMode(AudioLayer::NONE);
     }
 
     /* Direct IP to IP call */
@@ -1681,8 +1720,7 @@ void ManagerImpl::peerHungupCall(const std::string& call_id)
         }
     }
 
-    /* Broadcast a signal over DBus */
-    dbus_.getCallManager()->callStateChanged(call_id, "HUNGUP");
+    client_.getCallManager()->callStateChanged(call_id, "HUNGUP");
 
     removeWaitingCall(call_id);
     if (not incomingCallsWaiting())
@@ -1694,8 +1732,7 @@ void ManagerImpl::peerHungupCall(const std::string& call_id)
 //THREAD=VoIP
 void ManagerImpl::callBusy(const std::string& id)
 {
-    DEBUG("Call %s busy", id.c_str());
-    dbus_.getCallManager()->callStateChanged(id, "BUSY");
+    client_.getCallManager()->callStateChanged(id, "BUSY");
 
     if (isCurrentCall(id)) {
         playATone(Tone::TONE_BUSY);
@@ -1709,7 +1746,7 @@ void ManagerImpl::callBusy(const std::string& id)
 //THREAD=VoIP
 void ManagerImpl::callFailure(const std::string& call_id)
 {
-    dbus_.getCallManager()->callStateChanged(call_id, "FAILURE");
+    client_.getCallManager()->callStateChanged(call_id, "FAILURE");
 
     if (isCurrentCall(call_id)) {
         playATone(Tone::TONE_BUSY);
@@ -1730,7 +1767,7 @@ void ManagerImpl::callFailure(const std::string& call_id)
 void ManagerImpl::startVoiceMessageNotification(const std::string& accountId,
         int nb_msg)
 {
-    dbus_.getCallManager()->voiceMailNotify(accountId, nb_msg);
+    client_.getCallManager()->voiceMailNotify(accountId, nb_msg);
 }
 
 /**
@@ -1774,7 +1811,8 @@ void ManagerImpl::stopTone()
 
     if (audiofile_.get()) {
         std::string filepath(audiofile_->getFilePath());
-        dbus_.getCallManager()->recordPlaybackStopped(filepath);
+
+        client_.getCallManager()->recordPlaybackStopped(filepath);
         audiofile_.reset();
     }
 }
@@ -1811,10 +1849,21 @@ void ManagerImpl::ringback()
     playATone(Tone::TONE_RINGTONE);
 }
 
+// Caller must hold toneMutex
+void
+ManagerImpl::updateAudioFile(const std::string &file, int sampleRate)
+{
+    try {
+        audiofile_.reset(new AudioFile(file, sampleRate));
+    } catch (const AudioFileException &e) {
+        ERROR("Exception: %s", e.what());
+    }
+}
+
 /**
  * Multi Thread
  */
-void ManagerImpl::ringtone(const std::string& accountID)
+void ManagerImpl::playRingtone(const std::string& accountID)
 {
     Account *account = getAccount(accountID);
 
@@ -1853,25 +1902,11 @@ void ManagerImpl::ringtone(const std::string& accountID)
         sfl::ScopedLock m(toneMutex_);
 
         if (audiofile_.get()) {
-            dbus_.getCallManager()->recordPlaybackStopped(audiofile_->getFilePath());
+            client_.getCallManager()->recordPlaybackStopped(audiofile_->getFilePath());
             audiofile_.reset();
         }
 
-        try {
-            if (ringchoice.find(".wav") != std::string::npos)
-                audiofile_.reset(new WaveFile(ringchoice, audioLayerSmplr));
-            else {
-                sfl::AudioCodec *codec;
-                if (ringchoice.find(".ul") != std::string::npos or ringchoice.find(".au") != std::string::npos)
-                    codec = audioCodecFactory.getCodec(PAYLOAD_CODEC_ULAW);
-                else
-                    throw AudioFileException("Couldn't guess an appropriate decoder");
-
-                audiofile_.reset(new RawFile(ringchoice, static_cast<sfl::AudioCodec *>(codec), audioLayerSmplr));
-            }
-        } catch (const AudioFileException &e) {
-            ERROR("Exception: %s", e.what());
-        }
+        updateAudioFile(ringchoice, audioLayerSmplr);
     } // leave mutex
 
     sfl::ScopedLock lock(audioLayerMutex_);
@@ -1901,10 +1936,14 @@ ManagerImpl::getTelephoneFile()
 /**
  * Initialization: Main Thread
  */
-std::string ManagerImpl::createConfigFile() const
+std::string ManagerImpl::retrieveConfigPath() const
 {
+#ifdef __ANDROID__
+    std::string configdir = "/data/data/com.savoirfairelinux.sflphone";
+#else
     std::string configdir = fileutils::get_home_dir() + DIR_SEPARATOR_STR +
                             ".config" + DIR_SEPARATOR_STR + PACKAGE;
+#endif
 
     const std::string xdg_env(XDG_CONFIG_HOME);
     if (not xdg_env.empty())
@@ -1913,7 +1952,7 @@ std::string ManagerImpl::createConfigFile() const
     if (mkdir(configdir.data(), 0700) != 0) {
         // If directory creation failed
         if (errno != EEXIST)
-           DEBUG("Cannot create directory: %m");
+           DEBUG("Cannot create directory: %s!", configdir.c_str());
     }
 
     static const char * const PROGNAME = "sflphoned";
@@ -2091,7 +2130,7 @@ bool ManagerImpl::toggleRecordingCall(const std::string& id)
     }
 
     const bool result = rec->toggleRecording();
-    dbus_.getCallManager()->recordPlaybackFilepath(id, rec->getFilename());
+    client_.getCallManager()->recordPlaybackFilepath(id, rec->getFilename());
     return result;
 }
 
@@ -2121,16 +2160,13 @@ bool ManagerImpl::startRecordedFilePlayback(const std::string& filepath)
         sfl::ScopedLock m(toneMutex_);
 
         if (audiofile_.get()) {
-            dbus_.getCallManager()->recordPlaybackStopped(audiofile_->getFilePath());
+            client_.getCallManager()->recordPlaybackStopped(audiofile_->getFilePath());
             audiofile_.reset();
         }
 
-        try {
-            audiofile_.reset(new WaveFile(filepath, sampleRate));
-            audiofile_->setIsRecording(true);
-        } catch (const AudioFileException &e) {
-            ERROR("Exception: %s", e.what());
-        }
+        updateAudioFile(filepath, sampleRate);
+        if (not audiofile_)
+            return false;
     } // release toneMutex
 
     sfl::ScopedLock lock(audioLayerMutex_);
@@ -2160,6 +2196,7 @@ void ManagerImpl::stopRecordedFilePlayback(const std::string& filepath)
         sfl::ScopedLock m(toneMutex_);
         audiofile_.reset();
     }
+    client_.getCallManager()->recordPlaybackStopped(filepath);
 }
 
 void ManagerImpl::setHistoryLimit(int days)
@@ -2350,20 +2387,20 @@ std::vector<std::string> ManagerImpl::getAccountList() const
 
     // If no order has been set, load the default one ie according to the creation date.
     if (account_order.empty()) {
-        for (AccountMap::const_iterator iter = allAccounts.begin(); iter != allAccounts.end(); ++iter) {
-            if (iter->first == SIPAccount::IP2IP_PROFILE || iter->first.empty())
+        for (const auto &item : allAccounts) {
+            if (item.first == SIPAccount::IP2IP_PROFILE || item.first.empty())
                 continue;
 
-            if (iter->second)
-                v.push_back(iter->second->getAccountID());
+            if (item.second)
+                v.push_back(item.second->getAccountID());
         }
     }
     else {
-        for (vector<string>::const_iterator iter = account_order.begin(); iter != account_order.end(); ++iter) {
-            if (*iter == SIPAccount::IP2IP_PROFILE or iter->empty())
+        for (const auto &item : account_order) {
+            if (item == SIPAccount::IP2IP_PROFILE or item.empty())
                 continue;
 
-            AccountMap::const_iterator account_iter = allAccounts.find(*iter);
+            AccountMap::const_iterator account_iter = allAccounts.find(item);
 
             if (account_iter != allAccounts.end() and account_iter->second)
                 v.push_back(account_iter->second->getAccountID());
@@ -2420,7 +2457,7 @@ void ManagerImpl::setAccountDetails(const std::string& accountID,
         account->unregisterVoIPLink();
 
     // Update account details to the client side
-    dbus_.getConfigurationManager()->accountsChanged();
+    client_.getConfigurationManager()->accountsChanged();
 }
 
 std::string
@@ -2483,7 +2520,7 @@ ManagerImpl::addAccount(const std::map<std::string, std::string>& details)
 
     saveConfig();
 
-    dbus_.getConfigurationManager()->accountsChanged();
+    client_.getConfigurationManager()->accountsChanged();
 
     return accountID.str();
 }
@@ -2507,7 +2544,7 @@ void ManagerImpl::removeAccount(const std::string& accountID)
 
     saveConfig();
 
-    dbus_.getConfigurationManager()->accountsChanged();
+    client_.getConfigurationManager()->accountsChanged();
 }
 
 std::string ManagerImpl::getAccountFromCall(const std::string& callID)
@@ -2881,7 +2918,7 @@ void ManagerImpl::saveHistory()
     if (!history_.save())
         ERROR("Could not save history!");
     else
-        dbus_.getConfigurationManager()->historyChanged();
+        client_.getConfigurationManager()->historyChanged();
 }
 
 void ManagerImpl::clearHistory()
@@ -2912,3 +2949,57 @@ void ManagerImpl::sendPresence(const std::string& accountID, const std::string&
     SIPAccount *account = Manager::instance().getSipAccount(accountID);
     account->getPresence()->sendPresence(status,note);
 }
+
+void
+ManagerImpl::registerAccounts()
+{
+    AccountMap allAccounts(getAllAccounts());
+
+    for (auto &item : allAccounts) {
+        Account *a = item.second;
+
+        if (!a)
+            continue;
+
+        a->loadConfig();
+
+        if (a->isEnabled())
+            a->registerVoIPLink();
+    }
+}
+
+
+VoIPLink* ManagerImpl::getAccountLink(const std::string& accountID)
+{
+    Account *account = getAccount(accountID);
+    if (account == NULL) {
+        DEBUG("Could not find account for account %s, returning sip voip", accountID.c_str());
+        return SIPVoIPLink::instance();
+    }
+
+    if (not accountID.empty())
+        return account->getVoIPLink();
+    else {
+        DEBUG("Account id is empty for voip link, returning sip voip");
+        return SIPVoIPLink::instance();
+    }
+}
+
+
+void
+ManagerImpl::sendRegister(const std::string& accountID, bool enable)
+{
+    Account* acc = getAccount(accountID);
+    if (!acc)
+        return;
+
+    acc->setEnabled(enable);
+    acc->loadConfig();
+
+    Manager::instance().saveConfig();
+
+    if (acc->isEnabled())
+        acc->registerVoIPLink();
+    else
+        acc->unregisterVoIPLink();
+}
diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h
index c02431c63e8e64c4114655ab52e5d959c64d1e1d..db78baec8ca6aa8ada62b2fd081406cbae5c2055 100644
--- a/daemon/src/managerimpl.h
+++ b/daemon/src/managerimpl.h
@@ -43,10 +43,10 @@
 #include <vector>
 #include <set>
 #include <map>
-#include <tr1/memory>
-
+#include <memory>
 #include <pthread.h>
-#include "dbus/dbusmanager.h"
+
+#include "client/client.h"
 
 #include "config/sfl_config.h"
 
@@ -129,10 +129,14 @@ class ManagerImpl {
          */
         void init(const std::string &config_file);
 
+        void setPath(const std::string &path);
+
+#ifdef HAVE_DBUS
         /**
          * Enter Dbus mainloop
          */
         void run();
+#endif
 
         /*
          * Terminate all threads and exit DBus loop
@@ -706,13 +710,6 @@ class ManagerImpl {
          */
         std::string getConfigString(const std::string& section, const std::string& name) const;
 
-        /**
-         * Retrieve the soundcards index in the user config file and try to open audio devices
-         * with a specific alsa plugin.
-         * Set the audio layer sample rate
-         */
-        void selectAudioDriver();
-
         /**
          * Handle audio sounds heard by a caller while they wait for their
          * connection to a called party to be completed.
@@ -722,7 +719,7 @@ class ManagerImpl {
         /**
          * Handle played music when an incoming call occurs
          */
-        void ringtone(const std::string& accountID);
+        void playRingtone(const std::string& accountID);
 
         /**
          * Handle played music when a congestion occurs
@@ -788,6 +785,10 @@ class ManagerImpl {
         const AudioCodecFactory audioCodecFactory;
 
     private:
+        bool parseConfiguration();
+
+        // Set the ringtone or recorded call to be played
+        void updateAudioFile(const std::string &file, int sampleRate);
 
         /**
          * Get the Call referred to by callID. If the Call does not exist, return NULL
@@ -811,7 +812,7 @@ class ManagerImpl {
         /**
          * Create config directory in home user and return configuration file path
          */
-        std::string createConfigFile() const;
+        std::string retrieveConfigPath() const;
 
         /*
          * Initialize zeroconf module and scanning
@@ -835,7 +836,7 @@ class ManagerImpl {
          */
         void playATone(Tone::TONEID toneId);
 
-        DBusManager dbus_;
+        Client client_;
 
         /** The configuration tree. It contains accounts parameters, general user settings ,audio settings, ... */
         Conf::ConfigTree config_;
@@ -850,14 +851,14 @@ class ManagerImpl {
         AudioLayer* audiodriver_;
 
         // Main thread
-        std::tr1::shared_ptr<DTMF> dtmfKey_;
+        std::unique_ptr<DTMF> dtmfKey_;
 
         /////////////////////
         // Protected by Mutex
         /////////////////////
         pthread_mutex_t toneMutex_;
-        std::tr1::shared_ptr<TelephoneTone> telephoneTone_;
-        std::tr1::shared_ptr<AudioFile> audiofile_;
+        std::unique_ptr<TelephoneTone> telephoneTone_;
+        std::unique_ptr<AudioFile> audiofile_;
 
         // To handle volume control
         // short speakerVolume_;
@@ -950,16 +951,15 @@ class ManagerImpl {
         bool hasCurrentCall() const;
 
         /**
-         * Return the current DBusManager
-         * @return A pointer to the DBusManager instance
+         * Return the current Client
+         * @return A pointer to the Client instance
          */
-        DBusManager * getDbusManager() {
-            return &dbus_;
+        Client* getClient() {
+            return &client_;
         }
-
 #ifdef SFL_VIDEO
         VideoControls * getVideoControls() {
-            return dbus_.getVideoControls();
+            return client_.getVideoControls();
         }
 #endif
 
@@ -1017,12 +1017,6 @@ class ManagerImpl {
          */
         VoIPLink* getAccountLink(const std::string& accountID);
 
-        std::string getStunServer() const;
-        void setStunServer(const std::string &server);
-
-        int isStunEnabled();
-        void enableStun();
-
         // Map containing conference pointers
         ConferenceMap conferenceMap_;
 
diff --git a/daemon/src/managerimpl_registration.cpp b/daemon/src/managerimpl_registration.cpp
deleted file mode 100644
index 0e839cb66a5cd50e3dbd8298ce5671c9901f250f..0000000000000000000000000000000000000000
--- a/daemon/src/managerimpl_registration.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
- *  Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
- *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
- *  Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
- *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
- *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
- *  Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@savoirfairelinux.com>
- *
- *  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, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *  Additional permission under GNU GPL version 3 section 7:
- *
- *  If you modify this program, or any covered work, by linking or
- *  combining it with the OpenSSL project's OpenSSL library (or a
- *  modified version of that library), containing parts covered by the
- *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
- *  grants you additional permission to convey the resulting work.
- *  Corresponding Source for a non-source form of such a combination
- *  shall include the source code for the parts of OpenSSL used as well
- *  as that of the covered work.
- */
-
-#include "managerimpl.h"
-
-#include "account.h"
-#include "dbus/callmanager.h"
-#include "global.h"
-#include "logger.h"
-
-#include "audio/audiolayer.h"
-#include "sip/sipvoiplink.h"
-#include "manager.h"
-#include "dbus/configurationmanager.h"
-
-#include <cstdlib>
-
-void
-ManagerImpl::registerAccounts()
-{
-    AccountMap allAccounts(getAllAccounts());
-
-    for (AccountMap::iterator iter = allAccounts.begin(); iter != allAccounts.end(); ++iter) {
-        Account *a = iter->second;
-
-        if (!a)
-            continue;
-
-        a->loadConfig();
-
-        if (a->isEnabled())
-            a->registerVoIPLink();
-    }
-}
-
-
-VoIPLink* ManagerImpl::getAccountLink(const std::string& accountID)
-{
-    Account *account = getAccount(accountID);
-    if (account == NULL) {
-        DEBUG("Could not find account for account %s, returning sip voip", accountID.c_str());
-        return SIPVoIPLink::instance();
-    }
-
-    if (not accountID.empty())
-        return account->getVoIPLink();
-    else {
-        DEBUG("Account id is empty for voip link, returning sip voip");
-        return SIPVoIPLink::instance();
-    }
-}
-
-
-void
-ManagerImpl::sendRegister(const std::string& accountID, bool enable)
-{
-    Account* acc = getAccount(accountID);
-    if (!acc)
-        return;
-
-    acc->setEnabled(enable);
-    acc->loadConfig();
-
-    Manager::instance().saveConfig();
-
-    if (acc->isEnabled())
-        acc->registerVoIPLink();
-    else
-        acc->unregisterVoIPLink();
-}
diff --git a/daemon/src/numbercleaner.cpp b/daemon/src/numbercleaner.cpp
index 1044132d811a0543d9872b9e62f86a7c6cbbf24b..67b509dd75cc52a198ca48b57c7165c7a84be73c 100644
--- a/daemon/src/numbercleaner.cpp
+++ b/daemon/src/numbercleaner.cpp
@@ -37,9 +37,8 @@
 namespace {
 void strip_chars(const std::string &to_strip, std::string &num)
 {
-    for (std::string::const_iterator iter = to_strip.begin();
-            iter != to_strip.end(); ++iter)
-        num.erase(std::remove(num.begin(), num.end(), *iter), num.end());
+    for (const auto &item : to_strip)
+        num.erase(std::remove(num.begin(), num.end(), item), num.end());
 }
 }
 
diff --git a/daemon/src/preferences.cpp b/daemon/src/preferences.cpp
index 14038390d19f60eadc3e52572efa04d4e4ac02f7..1ac16dadd434d64071caaa1f24c6281409e7b61f 100644
--- a/daemon/src/preferences.cpp
+++ b/daemon/src/preferences.cpp
@@ -34,10 +34,17 @@
 
 #include "preferences.h"
 #include "logger.h"
+#include "audio/audiolayer.h"
+#ifdef __ANDROID__
+#include "audio/opensl/opensllayer.h"
+#else
+#if HAVE_ALSA
 #include "audio/alsa/alsalayer.h"
+#endif
 #if HAVE_PULSE
 #include "audio/pulseaudio/pulselayer.h"
 #endif
+#endif
 #include "config/yamlemitter.h"
 #include "config/yamlnode.h"
 #include "hooks/urlhook.h"
@@ -77,7 +84,9 @@ static const char * const URL_COMMAND_KEY = "urlCommand";
 static const char * const URL_SIP_FIELD_KEY = "urlSipField";
 
 // audio preferences
+#if HAVE_ALSA
 static const char * const ALSAMAP_KEY = "alsa";
+#endif
 #if HAVE_PULSE
 static const char * const PULSEMAP_KEY = "pulse";
 #endif
@@ -103,11 +112,11 @@ static const char * const POPUP_SHORT_KEY = "popupWindow";
 static const char * const TOGGLE_HOLD_SHORT_KEY = "toggleHold";
 static const char * const TOGGLE_PICKUP_HANGUP_SHORT_KEY = "togglePickupHangup";
 
-static const char * const DFT_PULSE_LENGTH_STR ="250";  /** Default DTMF lenght */
+static const char * const DFT_PULSE_LENGTH_STR = "250"; /** Default DTMF lenght */
 static const char * const ZRTP_ZIDFILE = "zidFile";     /** The filename used for storing ZIDs */
-static const char * const ALSA_DFT_CARD	= "0";          /** Default sound card index */
+static const char * const ALSA_DFT_CARD    = "0";          /** Default sound card index */
 static const char * const DFT_VOL_SPKR_STR = "100";     /** Default speaker volume */
-static const char * const DFT_VOL_MICRO_STR	= "100";    /** Default mic volume */
+static const char * const DFT_VOL_MICRO_STR    = "100";    /** Default mic volume */
 } // end anonymous namespace
 
 Preferences::Preferences() :
@@ -297,32 +306,47 @@ AudioPreference::AudioPreference() :
 {}
 
 namespace {
+#if HAVE_ALSA
 void checkSoundCard(int &card, AudioLayer::PCMType stream)
 {
     if (not AlsaLayer::soundCardIndexExists(card, stream)) {
         WARN(" Card with index %d doesn't exist or is unusable.", card);
         card = ALSA_DFT_CARD_ID;
     }
+
+    card = ALSA_DFT_CARD_ID;
 }
+#endif
 }
 
 AudioLayer* AudioPreference::createAudioLayer()
 {
+#ifdef __ANDROID__
+    return new OpenSLLayer();
+#endif
+
 #if HAVE_PULSE
+
     if (audioApi_ == PULSEAUDIO_API_STR) {
         if (system("pactl info > /dev/null") == 0)
             return new PulseLayer(*this);
         else
             WARN("pulseaudio daemon not running, falling back to ALSA");
     }
+
 #endif
 
+#if HAVE_ALSA
+
     audioApi_ = ALSA_API_STR;
     checkSoundCard(alsaCardin_, AudioLayer::SFL_PCM_CAPTURE);
     checkSoundCard(alsaCardout_, AudioLayer::SFL_PCM_PLAYBACK);
     checkSoundCard(alsaCardring_, AudioLayer::SFL_PCM_RINGTONE);
 
     return new AlsaLayer(*this);
+#else
+    return NULL;
+#endif
 }
 
 AudioLayer* AudioPreference::switchAndCreateAudioLayer()
@@ -379,12 +403,14 @@ void AudioPreference::serialize(Conf::YamlEmitter &emitter)
     preferencemap.setKeyValue(VOLUMESPKR_KEY, &volumespkr);
 
     Conf::MappingNode alsapreferencemap(NULL);
+#if HAVE_ALSA
     preferencemap.setKeyValue(ALSAMAP_KEY, &alsapreferencemap);
     alsapreferencemap.setKeyValue(CARDIN_KEY, &cardin);
     alsapreferencemap.setKeyValue(CARDOUT_KEY, &cardout);
     alsapreferencemap.setKeyValue(CARDRING_KEY, &cardring);
     alsapreferencemap.setKeyValue(PLUGIN_KEY, &plugin);
     alsapreferencemap.setKeyValue(SMPLRATE_KEY, &alsaSmplrate);
+#endif
 
 #if HAVE_PULSE
     Conf::MappingNode pulsepreferencemap(NULL);
@@ -417,6 +443,7 @@ void AudioPreference::unserialize(const Conf::YamlNode &map)
     map.getValue(AUDIO_API_KEY, &audioApi_);
     std::string tmpRecordPath;
     map.getValue(RECORDPATH_KEY, &tmpRecordPath);
+
     if (not setRecordPath(tmpRecordPath))
         setRecordPath(fileutils::get_home_dir());
 
@@ -426,7 +453,7 @@ void AudioPreference::unserialize(const Conf::YamlNode &map)
     map.getValue(NOISE_REDUCE_KEY, &noisereduce_);
     map.getValue(ECHO_CANCEL_KEY, &echocancel_);
 
-    Conf::MappingNode *alsamap =(Conf::MappingNode *) map.getValue("alsa");
+    Conf::MappingNode *alsamap = (Conf::MappingNode *) map.getValue("alsa");
 
     if (alsamap) {
         alsamap->getValue(CARDIN_KEY, &alsaCardin_);
@@ -437,13 +464,14 @@ void AudioPreference::unserialize(const Conf::YamlNode &map)
     }
 
 #if HAVE_PULSE
-    Conf::MappingNode *pulsemap =(Conf::MappingNode *)(map.getValue("pulse"));
+    Conf::MappingNode *pulsemap = (Conf::MappingNode *)(map.getValue("pulse"));
 
     if (pulsemap) {
         pulsemap->getValue(DEVICE_PLAYBACK_KEY, &pulseDevicePlayback_);
         pulsemap->getValue(DEVICE_RECORD_KEY, &pulseDeviceRecord_);
         pulsemap->getValue(DEVICE_RINGTONE_KEY, &pulseDeviceRingtone_);
     }
+
 #endif
 }
 
diff --git a/daemon/src/sfl_types.h b/daemon/src/sfl_types.h
index a69f0d19ab93f9ba0a14287aefa48a4c606bbb00..a95394493f7795a1854fd4650113379e37a870c0 100644
--- a/daemon/src/sfl_types.h
+++ b/daemon/src/sfl_types.h
@@ -32,10 +32,10 @@
 #define SFL_TYPES_H_
 
 #include <cstddef> // for size_t
+#include <stdint.h>
 
-typedef short SFLDataFormat;
-typedef signed short SINT16;
-typedef signed int SINT32;
+typedef int16_t SFLAudioSample;
+#define SFL_DATA_FORMAT_MAX SHRT_MAX
 
 static const size_t SIZEBUF = 400000; /** About 12 sec of buffering at 8000 Hz*/
 
diff --git a/daemon/src/sip/sdes_negotiator.cpp b/daemon/src/sip/sdes_negotiator.cpp
index df8c6085791f2053bfd1ac37669c7f0134a1ce27..26631e518d0c42fc1f003ade220bb1f26c15d4c4 100644
--- a/daemon/src/sip/sdes_negotiator.cpp
+++ b/daemon/src/sip/sdes_negotiator.cpp
@@ -32,7 +32,7 @@
 #include "pattern.h"
 
 #include <cstdio>
-#include <tr1/memory>
+#include <memory>
 #include <iostream>
 #include <sstream>
 #include <algorithm>
@@ -61,7 +61,7 @@ std::vector<CryptoAttribute *> SdesNegotiator::parse()
     // syntax :
     //a=crypto:tag 1*WSP crypto-suite 1*WSP key-params *(1*WSP session-param)
 
-    std::tr1::shared_ptr<Pattern> generalSyntaxPattern, tagPattern, cryptoSuitePattern,
+    std::unique_ptr<Pattern> generalSyntaxPattern, tagPattern, cryptoSuitePattern,
         keyParamsPattern;
 
     try {
@@ -93,14 +93,13 @@ std::vector<CryptoAttribute *> SdesNegotiator::parse()
 
     std::vector<CryptoAttribute *> cryptoAttributeVector;
 
-    for (std::vector<std::string>::iterator iter = remoteAttribute_.begin();
-            iter != remoteAttribute_.end(); ++iter) {
+    for (const auto &item : remoteAttribute_) {
 
         // Split the line into its component
         // that we will analyze further down.
         std::vector<std::string> sdesLine;
 
-        *generalSyntaxPattern << (*iter);
+        *generalSyntaxPattern << item;
 
         try {
             sdesLine = generalSyntaxPattern->split();
diff --git a/daemon/src/sip/sdp.cpp b/daemon/src/sip/sdp.cpp
index 1436af130087849f3b22cc4b415e65fe4215136f..64766b9dcb286a64905801ebc93f9aa001046302 100644
--- a/daemon/src/sip/sdp.cpp
+++ b/daemon/src/sip/sdp.cpp
@@ -40,6 +40,10 @@
 
 #include <algorithm>
 
+#ifdef HAVE_OPUS
+#include "audio/codecs/opus.h"
+#endif
+
 #ifdef SFL_VIDEO
 #include "video/libav_utils.h"
 #endif
@@ -76,8 +80,8 @@ Sdp::Sdp(pj_pool_t *pool)
 namespace {
     bool hasPayload(const std::vector<sfl::AudioCodec*> &codecs, int pt)
     {
-        for (std::vector<sfl::AudioCodec*>::const_iterator i = codecs.begin(); i != codecs.end(); ++i)
-            if (*i and (*i)->getPayloadType() == pt)
+        for (const auto &i : codecs)
+            if (i and i->getPayloadType() == pt)
                 return true;
         return false;
     }
@@ -219,12 +223,14 @@ Sdp::setMediaDescriptorLines(bool audio)
         unsigned clock_rate;
         string enc_name;
         int payload;
+        unsigned channels;
 
         if (audio) {
             sfl::AudioCodec *codec = audio_codec_list_[i];
             payload = codec->getPayloadType();
             enc_name = codec->getMimeSubtype();
             clock_rate = codec->getClockRate();
+            channels = codec->getChannels();
             // G722 require G722/8000 media description even if it is 16000 codec
             if (codec->getPayloadType () == 9)
                 clock_rate = 8000;
@@ -248,13 +254,34 @@ Sdp::setMediaDescriptorLines(bool audio)
         rtpmap.pt = med->desc.fmt[i];
         rtpmap.enc_name = pj_str((char*) enc_name.c_str());
         rtpmap.clock_rate = clock_rate;
-        rtpmap.param.ptr = ((char* const)"");
-        rtpmap.param.slen = 0;
+
+#ifdef HAVE_OPUS
+        // Opus sample rate is allways declared as 48000 and channel num is allways 2 in rtpmap as per
+        // http://tools.ietf.org/html/draft-spittka-payload-rtp-opus-03#section-6.2
+        if(payload == Opus::PAYLOAD_TYPE) {
+            rtpmap.clock_rate = 48000;
+            rtpmap.param.ptr = ((char* const)"2");
+            rtpmap.param.slen = 1;
+        } else
+#endif
+        {
+            rtpmap.param.ptr = ((char* const)"");
+            rtpmap.param.slen = 0;
+        }
 
         pjmedia_sdp_attr *attr;
         pjmedia_sdp_rtpmap_to_attr(memPool_, &rtpmap, &attr);
 
         med->attr[med->attr_count++] = attr;
+
+#ifdef HAVE_OPUS
+        // Declare stereo support for opus
+        if(payload == Opus::PAYLOAD_TYPE) {
+            std::ostringstream os;
+            os << "fmtp:" << payload << " stereo=1; sprop-stereo=" << (channels>1 ? 1 : 0);
+            med->attr[med->attr_count++] = pjmedia_sdp_attr_create(memPool_, os.str().c_str(), NULL);
+        }
+#endif
 #ifdef SFL_VIDEO
         if (enc_name == "H264") {
             std::ostringstream os;
@@ -350,8 +377,8 @@ void Sdp::setLocalMediaAudioCapabilities(const vector<int> &selectedCodecs)
         WARN("No selected codec while building local SDP offer");
 
     audio_codec_list_.clear();
-    for (vector<int>::const_iterator i = selectedCodecs.begin(); i != selectedCodecs.end(); ++i) {
-        sfl::AudioCodec *codec = Manager::instance().audioCodecFactory.getCodec(*i);
+    for (const auto &i : selectedCodecs) {
+        sfl::AudioCodec *codec = Manager::instance().audioCodecFactory.getCodec(i);
 
         if (codec)
             audio_codec_list_.push_back(codec);
@@ -455,8 +482,9 @@ void Sdp::receiveOffer(const pjmedia_sdp_session* remote,
 
     remoteSession_ = pjmedia_sdp_session_clone(memPool_, remote);
 
-    pjmedia_sdp_neg_create_w_remote_offer(memPool_, localSession_,
-                                          remoteSession_, &negotiator_);
+    if (pjmedia_sdp_neg_create_w_remote_offer(memPool_, localSession_,
+            remoteSession_, &negotiator_) != PJ_SUCCESS)
+        ERROR("Failed to initialize negotiator");
 }
 
 void Sdp::startNegotiation()
@@ -505,9 +533,9 @@ string Sdp::getLineFromSession(const pjmedia_sdp_session *sess, const string &ke
     int size = pjmedia_sdp_print(sess, buffer, sizeof buffer);
     string sdp(buffer, size);
     const vector<string> tokens(split(sdp, '\n'));
-    for (vector<string>::const_iterator iter = tokens.begin(); iter != tokens.end(); ++iter)
-        if ((*iter).find(keyword) != string::npos)
-            return *iter;
+    for (const auto &item : tokens)
+        if (item.find(keyword) != string::npos)
+            return item;
     return "";
 }
 
@@ -619,9 +647,8 @@ Sdp::getProfileLevelID(const pjmedia_sdp_session *session,
 
 void Sdp::addSdesAttribute(const vector<std::string>& crypto)
 {
-    for (vector<std::string>::const_iterator iter = crypto.begin();
-            iter != crypto.end(); ++iter) {
-        pj_str_t val = { (char*)(*iter).c_str(), static_cast<pj_ssize_t>((*iter).size()) };
+    for (const auto &item : crypto) {
+        pj_str_t val = { (char*) item.c_str(), static_cast<pj_ssize_t>(item.size()) };
         pjmedia_sdp_attr *attr = pjmedia_sdp_attr_create(memPool_, "crypto", &val);
 
         for (unsigned i = 0; i < localSession_->media_count; i++)
@@ -765,6 +792,8 @@ bool Sdp::getOutgoingVideoSettings(map<string, string> &args) const
         }
         return true;
     }
+#else
+    (void) args;
 #endif
     return false;
 }
diff --git a/daemon/src/sip/sip_utils.cpp b/daemon/src/sip/sip_utils.cpp
index e61b286a9dcf3320840724b6ee2cc3b6da3f5ff4..82a3b07dd334ec9edd000bf0c75cbc1fbafbd717 100644
--- a/daemon/src/sip/sip_utils.cpp
+++ b/daemon/src/sip/sip_utils.cpp
@@ -165,7 +165,7 @@ sip_utils::getIPList(const std::string &name)
     for (struct addrinfo *res = result; res != NULL; res = res->ai_next) {
 
         void *ptr = 0;
-        std::string addrstr;
+        std::vector<char> addrstr;
         static const int AF_INET_STRLEN = 16, AF_INET6_STRLEN = 40;
         switch (res->ai_family) {
             case AF_INET:
@@ -180,11 +180,12 @@ sip_utils::getIPList(const std::string &name)
                 ERROR("Unexpected address family type, skipping.");
                 continue;
         }
-        inet_ntop(res->ai_family, ptr, &(*addrstr.begin()), addrstr.size());
+        inet_ntop(res->ai_family, ptr, addrstr.data(), addrstr.size());
         // don't add duplicates, and don't use an std::set because
         // we want this order preserved.
-        if (std::find(ipList.begin(), ipList.end(), addrstr) == ipList.end())
-            ipList.push_back(addrstr);
+        const std::string tmp(addrstr.begin(), addrstr.end());
+        if (std::find(ipList.begin(), ipList.end(), tmp) == ipList.end())
+            ipList.push_back(tmp);
     }
 
     freeaddrinfo(result);
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index f5b83284e9999a287c3b75cfd5ef81dc4b8ce216..c37b515285f9bd3aa1bf9882cb6ac9b3c88aa3b0 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -43,6 +43,7 @@
 #include "config/yamlemitter.h"
 #include "logger.h"
 #include "manager.h"
+#include <unistd.h>
 #include <pwd.h>
 #include <sstream>
 #include <algorithm>
@@ -60,10 +61,10 @@ const char * const SIPAccount::SIPINFO_STR = "sipinfo";
 const char * const SIPAccount::ACCOUNT_TYPE = "SIP";
 
 namespace {
-    const int MIN_REGISTRATION_TIME = 60;
-    const int DEFAULT_REGISTRATION_TIME = 3600;
-    const char *const TRUE_STR = "true";
-    const char *const FALSE_STR = "false";
+const int MIN_REGISTRATION_TIME = 60;
+const int DEFAULT_REGISTRATION_TIME = 3600;
+const char *const TRUE_STR = "true";
+const char *const FALSE_STR = "false";
 }
 
 SIPAccount::SIPAccount(const std::string& accountID)
@@ -83,7 +84,7 @@ SIPAccount::SIPAccount(const std::string& accountID)
     , transportType_(PJSIP_TRANSPORT_UNSPECIFIED)
     , cred_()
     , tlsSetting_()
-    , ciphers(100)
+    , ciphers_(100)
     , stunServerName_()
     , stunPort_(PJ_STUN_PORT)
     , dtmfType_(OVERRTP_STR)
@@ -117,6 +118,8 @@ SIPAccount::SIPAccount(const std::string& accountID)
     , receivedParameter_("")
     , rPort_(-1)
     , via_addr_()
+    , audioPortRange_(16384, 32766)
+    , videoPortRange_(49152, 65534)
 {
     via_addr_.host.ptr = 0;
     via_addr_.host.slen = 0;
@@ -171,8 +174,8 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
 #ifdef SFL_VIDEO
     SequenceNode videoCodecs(NULL);
     accountmap.setKeyValue(VIDEO_CODECS_KEY, &videoCodecs);
-    for (vector<map<string, string> >::iterator i = videoCodecList_.begin(); i != videoCodecList_.end(); ++i) {
-        map<string, string> &codec = *i;
+
+    for (auto &codec : videoCodecList_) {
         MappingNode *mapNode = new MappingNode(NULL);
         mapNode->setKeyValue(VIDEO_CODEC_NAME, new ScalarNode(codec[VIDEO_CODEC_NAME]));
         mapNode->setKeyValue(VIDEO_CODEC_BITRATE, new ScalarNode(codec[VIDEO_CODEC_BITRATE]));
@@ -180,6 +183,7 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
         mapNode->setKeyValue(VIDEO_CODEC_PARAMETERS, new ScalarNode(codec[VIDEO_CODEC_PARAMETERS]));
         videoCodecs.addNode(mapNode);
     }
+
 #endif
 
     ScalarNode ringtonePath(ringtonePath_);
@@ -256,10 +260,8 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
     SequenceNode credentialseq(NULL);
     accountmap.setKeyValue(CRED_KEY, &credentialseq);
 
-    std::vector<std::map<std::string, std::string> >::const_iterator it;
-
-    for (it = credentials_.begin(); it != credentials_.end(); ++it) {
-        std::map<std::string, std::string> cred = *it;
+    for (const auto &it : credentials_) {
+        std::map<std::string, std::string> cred = it;
         MappingNode *map = new MappingNode(NULL);
         map->setKeyValue(CONFIG_ACCOUNT_USERNAME, new ScalarNode(cred[CONFIG_ACCOUNT_USERNAME]));
         map->setKeyValue(CONFIG_ACCOUNT_PASSWORD, new ScalarNode(cred[CONFIG_ACCOUNT_PASSWORD]));
@@ -282,6 +284,9 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
     tlsmap.setKeyValue(VERIFY_CLIENT_KEY, &verifyclient);
     tlsmap.setKeyValue(VERIFY_SERVER_KEY, &verifyserver);
 
+    ScalarNode userAgent(userAgent_);
+    accountmap.setKeyValue(USER_AGENT_KEY, &userAgent);
+
     try {
         emitter.serializeAccount(&accountmap);
     } catch (const YamlEmitterException &e) {
@@ -290,8 +295,9 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
 
     // Cleanup
     Sequence *credSeq = credentialseq.getSequence();
-    for (Sequence::iterator seqit = credSeq->begin(); seqit != credSeq->end(); ++seqit) {
-        MappingNode *node = static_cast<MappingNode*>(*seqit);
+
+    for (const auto &seqit : *credSeq) {
+        MappingNode *node = static_cast<MappingNode*>(seqit);
         delete node->getValue(CONFIG_ACCOUNT_USERNAME);
         delete node->getValue(CONFIG_ACCOUNT_PASSWORD);
         delete node->getValue(CONFIG_ACCOUNT_REALM);
@@ -300,14 +306,16 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
 
 #ifdef SFL_VIDEO
     Sequence *videoCodecSeq = videoCodecs.getSequence();
-    for (Sequence::iterator i = videoCodecSeq->begin(); i != videoCodecSeq->end(); ++i) {
-        MappingNode *node = static_cast<MappingNode*>(*i);
+
+    for (auto &i : *videoCodecSeq) {
+        MappingNode *node = static_cast<MappingNode*>(i);
         delete node->getValue(VIDEO_CODEC_NAME);
         delete node->getValue(VIDEO_CODEC_BITRATE);
         delete node->getValue(VIDEO_CODEC_ENABLED);
         delete node->getValue(VIDEO_CODEC_PARAMETERS);
         delete node;
     }
+
 #endif
 }
 
@@ -320,10 +328,14 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
 
     mapNode.getValue(ALIAS_KEY, &alias_);
     mapNode.getValue(USERNAME_KEY, &username_);
+
     if (not isIP2IP()) mapNode.getValue(HOSTNAME_KEY, &hostname_);
+
     mapNode.getValue(ACCOUNT_ENABLE_KEY, &enabled_);
     mapNode.getValue(ACCOUNT_AUTOANSWER_KEY, &autoAnswerEnabled_);
+
     if (not isIP2IP()) mapNode.getValue(MAILBOX_KEY, &mailBox_);
+
     mapNode.getValue(AUDIO_CODECS_KEY, &audioCodecStr_);
     // Update codec list which one is used for SDP offer
     setActiveAudioCodecs(split_string(audioCodecStr_));
@@ -333,14 +345,16 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
     if (videoCodecsNode and videoCodecsNode->getType() == SEQUENCE) {
         SequenceNode *videoCodecs = static_cast<SequenceNode *>(videoCodecsNode);
         Sequence *seq = videoCodecs->getSequence();
+
         if (seq->empty()) {
             // Video codecs are an empty list
             WARN("Loading default video codecs");
             videoCodecList_ = libav_utils::getDefaultCodecs();
         } else {
             vector<map<string, string> > videoCodecDetails;
-            for (Sequence::iterator it = seq->begin(); it != seq->end(); ++it) {
-                MappingNode *codec = static_cast<MappingNode *>(*it);
+
+            for (auto it : *seq) {
+                MappingNode *codec = static_cast<MappingNode *>(it);
                 map<string, string> codecMap;
                 codec->getValue(VIDEO_CODEC_NAME, &codecMap[VIDEO_CODEC_NAME]);
                 codec->getValue(VIDEO_CODEC_BITRATE, &codecMap[VIDEO_CODEC_BITRATE]);
@@ -348,6 +362,7 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
                 codec->getValue(VIDEO_CODEC_PARAMETERS, &codecMap[VIDEO_CODEC_PARAMETERS]);
                 videoCodecDetails.push_back(codecMap);
             }
+
             // these must be validated
             setVideoCodecs(videoCodecDetails);
         }
@@ -357,11 +372,14 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
         WARN("Loading default video codecs");
         videoCodecList_ = libav_utils::getDefaultCodecs();
     }
+
 #endif
 
     mapNode.getValue(RINGTONE_PATH_KEY, &ringtonePath_);
     mapNode.getValue(RINGTONE_ENABLED_KEY, &ringtoneEnabled_);
+
     if (not isIP2IP()) mapNode.getValue(Preferences::REGISTRATION_EXPIRE_KEY, &registrationExpire_);
+
     mapNode.getValue(INTERFACE_KEY, &interface_);
     int port = DEFAULT_SIP_PORT;
     mapNode.getValue(PORT_KEY, &port);
@@ -370,6 +388,7 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
     mapNode.getValue(PUBLISH_PORT_KEY, &port);
     publishedPort_ = port;
     mapNode.getValue(SAME_AS_LOCAL_KEY, &publishedSameasLocal_);
+
     if (not isIP2IP()) mapNode.getValue(KEEP_ALIVE_ENABLED, &keepAliveEnabled_);
 
     std::string dtmfType;
@@ -380,6 +399,7 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
 
     // stun enabled
     if (not isIP2IP()) mapNode.getValue(STUN_ENABLED_KEY, &stunEnabled_);
+
     if (not isIP2IP()) mapNode.getValue(STUN_SERVER_KEY, &stunServer_);
 
     // Init stun server name with default server name
@@ -397,11 +417,10 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
      */
     if (credNode && credNode->getType() == SEQUENCE) {
         SequenceNode *credSeq = static_cast<SequenceNode *>(credNode);
-        Sequence::iterator it;
         Sequence *seq = credSeq->getSequence();
 
-        for (it = seq->begin(); it != seq->end(); ++it) {
-            MappingNode *cred = static_cast<MappingNode *>(*it);
+        for (auto it : *seq) {
+            MappingNode *cred = static_cast<MappingNode *>(it);
             std::string user;
             std::string pass;
             std::string realm;
@@ -420,6 +439,7 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
         // migration from old file format
         std::map<std::string, std::string> credmap;
         std::string password;
+
         if (not isIP2IP()) mapNode.getValue(PASSWORD_KEY, &password);
 
         credmap[CONFIG_ACCOUNT_USERNAME] = username_;
@@ -471,6 +491,7 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
         tlsMap->getValue(TIMEOUT_KEY, &tlsNegotiationTimeoutSec_);
         tlsMap->getValue(TIMEOUT_KEY, &tlsNegotiationTimeoutMsec_);
     }
+    mapNode.getValue(USER_AGENT_KEY, &userAgent_);
 }
 
 void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
@@ -495,15 +516,18 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
     publishedIpAddress_ = details[CONFIG_PUBLISHED_ADDRESS];
     localPort_ = atoi(details[CONFIG_LOCAL_PORT].c_str());
     publishedPort_ = atoi(details[CONFIG_PUBLISHED_PORT].c_str());
+
     if (stunServer_ != details[CONFIG_STUN_SERVER]) {
         link_->sipTransport.destroyStunResolver(stunServer_);
         // pj_stun_sock_destroy(pj_stun_sock *stun_sock);
     }
+
     stunServer_ = details[CONFIG_STUN_SERVER];
     stunEnabled_ = details[CONFIG_STUN_ENABLE] == TRUE_STR;
     dtmfType_ = details[CONFIG_ACCOUNT_DTMF_TYPE];
     registrationExpire_ = atoi(details[CONFIG_ACCOUNT_REGISTRATION_EXPIRE].c_str());
-    if(registrationExpire_ < MIN_REGISTRATION_TIME)
+
+    if (registrationExpire_ < MIN_REGISTRATION_TIME)
         registrationExpire_ = MIN_REGISTRATION_TIME;
 
     userAgent_ = details[CONFIG_ACCOUNT_USERAGENT];
@@ -545,6 +569,25 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
     }
 }
 
+static std::string retrievePassword(const std::map<std::string, std::string>& map, const std::string &username)
+{
+    std::map<std::string, std::string>::const_iterator map_iter_username;
+    std::map<std::string, std::string>::const_iterator map_iter_password;
+    map_iter_username = map.find(CONFIG_ACCOUNT_USERNAME);
+
+    if (map_iter_username != map.end()) {
+        if (map_iter_username->second == username) {
+            map_iter_password = map.find(CONFIG_ACCOUNT_PASSWORD);
+
+            if (map_iter_password != map.end()) {
+                return map_iter_password->second;
+            }
+        }
+    }
+
+    return "";
+}
+
 std::map<std::string, std::string> SIPAccount::getAccountDetails() const
 {
     std::map<std::string, std::string> a;
@@ -554,10 +597,22 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     a[CONFIG_ACCOUNT_ALIAS] = alias_;
 
     a[CONFIG_ACCOUNT_ENABLE] = enabled_ ? TRUE_STR : FALSE_STR;
-    a[CONFIG_ACCOUNT_AUTOANSWER]= autoAnswerEnabled_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_ACCOUNT_AUTOANSWER] = autoAnswerEnabled_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_ACCOUNT_TYPE] = ACCOUNT_TYPE;
     a[CONFIG_ACCOUNT_HOSTNAME] = hostname_;
     a[CONFIG_ACCOUNT_USERNAME] = username_;
+    // get password for this username
+    a[CONFIG_ACCOUNT_PASSWORD] = "";
+
+    if (hasCredentials()) {
+
+        for (const auto &vect_item : credentials_) {
+            const std::string password = retrievePassword(vect_item, username_);
+
+            if (not password.empty())
+                a[CONFIG_ACCOUNT_PASSWORD] = password;
+        }
+    }
 
     a[CONFIG_RINGTONE_PATH] = ringtonePath_;
     a[CONFIG_RINGTONE_ENABLED] = ringtoneEnabled_ ? TRUE_STR : FALSE_STR;
@@ -578,7 +633,7 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
         registrationStateDescription = registrationStateDetailed_.second;
     }
 
-    a[CONFIG_ACCOUNT_REGISTRATION_STATUS] = isIP2IP() ? "READY": mapStateNumberToString(state);
+    a[CONFIG_ACCOUNT_REGISTRATION_STATUS] = isIP2IP() ? "READY" : mapStateNumberToString(state);
     a[CONFIG_ACCOUNT_REGISTRATION_STATE_CODE] = registrationStateCode;
     a[CONFIG_ACCOUNT_REGISTRATION_STATE_DESC] = registrationStateDescription;
 
@@ -640,12 +695,14 @@ void SIPAccount::registerVoIPLink()
         return;
 
 #if HAVE_TLS
+
     // Init TLS settings if the user wants to use TLS
     if (tlsEnable_ == TRUE_STR) {
         DEBUG("TLS is enabled for account %s", accountID_.c_str());
         transportType_ = PJSIP_TRANSPORT_TLS;
         initTlsConfiguration();
     }
+
 #endif
 
     // Init STUN settings for this account if the user selected it
@@ -681,7 +738,8 @@ void SIPAccount::unregisterVoIPLink()
     }
 }
 
-void SIPAccount::startKeepAliveTimer() {
+void SIPAccount::startKeepAliveTimer()
+{
 
     if (isTlsEnabled())
         return;
@@ -745,26 +803,39 @@ pjsip_ssl_method SIPAccount::sslMethodStringToPjEnum(const std::string& method)
     return PJSIP_SSL_UNSPECIFIED_METHOD;
 }
 
-void SIPAccount::displayCipherSuite()
+void SIPAccount::trimCiphers()
 {
-    CipherArray::const_iterator iter;
-    for (iter = ciphers.begin(); iter != ciphers.end(); ++iter)
-        DEBUG("Cipher: %s", pj_ssl_cipher_name(*iter));
+    int sum = 0;
+    int count = 0;
+    // PJSIP aborts if our cipher list exceeds 1010 characters
+    static const int MAX_CIPHERS_STRLEN = 1010;
+
+    for (const auto &item : ciphers_) {
+        sum += strlen(pj_ssl_cipher_name(item));
+
+        if (sum > MAX_CIPHERS_STRLEN)
+            break;
+
+        ++count;
+    }
+
+    ciphers_.resize(count);
+    DEBUG("Using %u ciphers", ciphers_.size());
 }
 
 void SIPAccount::initTlsConfiguration()
 {
-    pj_status_t status;
     unsigned cipherNum;
 
     // Determine the cipher list supported on this machine
-    cipherNum = ciphers.size();
-    status = pj_ssl_cipher_get_availables(&ciphers.front(), &cipherNum);
-    if (status != PJ_SUCCESS) {
+    cipherNum = ciphers_.size();
+
+    if (pj_ssl_cipher_get_availables(&ciphers_.front(), &cipherNum) != PJ_SUCCESS)
         ERROR("Could not determine cipher list on this system");
-    }
 
-    ciphers.resize(cipherNum);
+    ciphers_.resize(cipherNum);
+
+    trimCiphers();
 
     // TLS listener is unique and should be only modified through IP2IP_PROFILE
     pjsip_tls_setting_default(&tlsSetting_);
@@ -774,12 +845,12 @@ void SIPAccount::initTlsConfiguration()
     pj_cstr(&tlsSetting_.privkey_file, tlsPrivateKeyFile_.c_str());
     pj_cstr(&tlsSetting_.password, tlsPassword_.c_str());
     tlsSetting_.method = sslMethodStringToPjEnum(tlsMethod_);
-    tlsSetting_.ciphers_num = ciphers.size();
-    tlsSetting_.ciphers = &ciphers.front();
+    tlsSetting_.ciphers_num = ciphers_.size();
+    tlsSetting_.ciphers = &ciphers_.front();
 
-    tlsSetting_.verify_server = tlsVerifyServer_ ? PJ_TRUE: PJ_FALSE;
-    tlsSetting_.verify_client = tlsVerifyClient_ ? PJ_TRUE: PJ_FALSE;
-    tlsSetting_.require_client_cert = tlsRequireClientCertificate_ ? PJ_TRUE: PJ_FALSE;
+    tlsSetting_.verify_server = tlsVerifyServer_;
+    tlsSetting_.verify_client = tlsVerifyClient_;
+    tlsSetting_.require_client_cert = tlsRequireClientCertificate_;
 
     tlsSetting_.timeout.sec = atol(tlsNegotiationTimeoutSec_.c_str());
     tlsSetting_.timeout.msec = atol(tlsNegotiationTimeoutMsec_.c_str());
@@ -787,6 +858,7 @@ void SIPAccount::initTlsConfiguration()
     tlsSetting_.qos_type = PJ_QOS_TYPE_BEST_EFFORT;
     tlsSetting_.qos_ignore_error = PJ_TRUE;
 }
+
 #endif
 
 void SIPAccount::initStunConfiguration()
@@ -817,6 +889,7 @@ void SIPAccount::loadConfig()
         registrationExpire_ = DEFAULT_REGISTRATION_TIME; /** Default expire value for registration */
 
 #if HAVE_TLS
+
     if (tlsEnable_ == TRUE_STR) {
         initTlsConfiguration();
         transportType_ = PJSIP_TRANSPORT_TLS;
@@ -836,19 +909,21 @@ bool SIPAccount::userMatch(const std::string& username) const
 }
 
 namespace {
-    bool haveValueInCommon(const std::vector<std::string> &a, const std::vector<std::string> &b)
-    {
-        for (std::vector<std::string>::const_iterator i = a.begin(); i != a.end(); ++i)
-            if (std::find(b.begin(), b.end(), *i) != b.end())
-                return true;
-        return false;
-    }
+bool haveValueInCommon(const std::vector<std::string> &a, const std::vector<std::string> &b)
+{
+    for (const auto &i : a)
+        if (std::find(b.begin(), b.end(), i) != b.end())
+            return true;
+
+    return false;
+}
 }
 
 bool SIPAccount::hostnameMatch(const std::string& hostname, pjsip_endpoint * /*endpt*/, pj_pool_t * /*pool*/) const
 {
     if (hostname == hostname_)
         return true;
+
     const std::vector<std::string> a(sip_utils::getIPList(hostname));
     const std::vector<std::string> b(sip_utils::getIPList(hostname_));
     return haveValueInCommon(a, b);
@@ -858,6 +933,7 @@ bool SIPAccount::proxyMatch(const std::string& hostname, pjsip_endpoint * /*endp
 {
     if (hostname == serviceRoute_)
         return true;
+
     const std::vector<std::string> a(sip_utils::getIPList(hostname));
     const std::vector<std::string> b(sip_utils::getIPList(serviceRoute_));
     return haveValueInCommon(a, b);
@@ -943,6 +1019,7 @@ std::string SIPAccount::getContactHeader() const
 
     // The transport type must be specified, in our case START_OTHER refers to stun transport
     pjsip_transport_type_e transportType = transportType_;
+
     if (transportType == PJSIP_TRANSPORT_START_OTHER)
         transportType = PJSIP_TRANSPORT_UDP;
 
@@ -953,7 +1030,7 @@ std::string SIPAccount::getContactHeader() const
     link_->sipTransport.findLocalAddressFromTransport(transport_, transportType, address, port);
 
     if (!receivedParameter_.empty())
-       address = receivedParameter_;
+        address = receivedParameter_;
 
     if (rPort_ != -1) {
         portstr << rPort_;
@@ -963,6 +1040,7 @@ std::string SIPAccount::getContactHeader() const
     // UDP does not require the transport specification
     std::string scheme;
     std::string transport;
+
     if (transportType_ == PJSIP_TRANSPORT_TLS) {
         scheme = "sips:";
         transport = ";transport=" + std::string(pjsip_transport_get_type_name(transportType));
@@ -1002,8 +1080,8 @@ void SIPAccount::keepAliveRegistrationCb(UNUSED pj_timer_heap_t *th, pj_timer_en
 
 namespace {
 std::string computeMd5HashFromCredential(const std::string& username,
-                                         const std::string& password,
-                                         const std::string& realm)
+        const std::string& password,
+        const std::string& realm)
 {
 #define MD5_APPEND(pms,buf,len) pj_md5_update(pms, (const pj_uint8_t*)buf, len)
 
@@ -1024,7 +1102,7 @@ std::string computeMd5HashFromCredential(const std::string& username,
     char hash[32];
 
     for (int i = 0; i < 16; ++i)
-        pj_val_to_hex_digit(digest[i], &hash[2*i]);
+        pj_val_to_hex_digit(digest[i], &hash[2 * i]);
 
     return std::string(hash, 32);
 }
@@ -1047,13 +1125,13 @@ void SIPAccount::setCredentials(const std::vector<std::map<std::string, std::str
     credentials_ = creds;
 
     /* md5 hashing */
-    for (vector<map<string, string> >::iterator it = credentials_.begin(); it != credentials_.end(); ++it) {
-        map<string, string>::const_iterator val = (*it).find(CONFIG_ACCOUNT_USERNAME);
-        const std::string username = val != (*it).end() ? val->second : "";
-        val = (*it).find(CONFIG_ACCOUNT_REALM);
-        const std::string realm(val != (*it).end() ? val->second : "");
-        val = (*it).find(CONFIG_ACCOUNT_PASSWORD);
-        const std::string password(val != (*it).end() ? val->second : "");
+    for (auto &it : credentials_) {
+        map<string, string>::const_iterator val = it.find(CONFIG_ACCOUNT_USERNAME);
+        const std::string username = val != it.end() ? val->second : "";
+        val = it.find(CONFIG_ACCOUNT_REALM);
+        const std::string realm(val != it.end() ? val->second : "");
+        val = it.find(CONFIG_ACCOUNT_PASSWORD);
+        const std::string password(val != it.end() ? val->second : "");
 
         if (md5HashingEnabled) {
             // TODO: Fix this.
@@ -1066,7 +1144,7 @@ void SIPAccount::setCredentials(const std::vector<std::map<std::string, std::str
             // re-hash a hashed password.
 
             if (password.length() != 32)
-                (*it)[CONFIG_ACCOUNT_PASSWORD] = computeMd5HashFromCredential(username, password, realm);
+                it[CONFIG_ACCOUNT_PASSWORD] = computeMd5HashFromCredential(username, password, realm);
         }
     }
 
@@ -1074,24 +1152,24 @@ void SIPAccount::setCredentials(const std::vector<std::map<std::string, std::str
     cred_.resize(credentials_.size());
 
     size_t i = 0;
-    for (vector<map<string, string > >::const_iterator iter = credentials_.begin();
-            iter != credentials_.end(); ++iter) {
-        map<string, string>::const_iterator val = (*iter).find(CONFIG_ACCOUNT_PASSWORD);
-        const std::string password = val != (*iter).end() ? val->second : "";
+
+    for (const auto &item : credentials_) {
+        map<string, string>::const_iterator val = item.find(CONFIG_ACCOUNT_PASSWORD);
+        const std::string password = val != item.end() ? val->second : "";
         int dataType = (md5HashingEnabled and password.length() == 32)
                        ? PJSIP_CRED_DATA_DIGEST
                        : PJSIP_CRED_DATA_PLAIN_PASSWD;
 
-        val = (*iter).find(CONFIG_ACCOUNT_USERNAME);
+        val = item.find(CONFIG_ACCOUNT_USERNAME);
 
-        if (val != (*iter).end())
+        if (val != item.end())
             cred_[i].username = pj_str((char*) val->second.c_str());
 
         cred_[i].data = pj_str((char*) password.c_str());
 
-        val = (*iter).find(CONFIG_ACCOUNT_REALM);
+        val = item.find(CONFIG_ACCOUNT_REALM);
 
-        if (val != (*iter).end())
+        if (val != item.end())
             cred_[i].realm = pj_str((char*) val->second.c_str());
 
         cred_[i].data_type = dataType;
@@ -1108,12 +1186,7 @@ SIPAccount::getCredentials() const
 
 std::string SIPAccount::getUserAgentName() const
 {
-    std::string result(userAgent_);
-
-    if (result == "sflphone" or result.empty())
-        result += "/" PACKAGE_VERSION;
-
-    return result;
+    return userAgent_.empty() ? DEFAULT_USER_AGENT : userAgent_;
 }
 
 std::map<std::string, std::string> SIPAccount::getIp2IpDetails() const
@@ -1314,3 +1387,27 @@ bool SIPAccount::matches(const std::string &userName, const std::string &server,
     } else
         return false;
 }
+
+namespace {
+    // returns even number in range [lower, upper]
+    unsigned int getRandomEvenNumber(const std::pair<unsigned, unsigned> &range)
+    {
+        const unsigned halfUpper = range.second * 0.5;
+        const unsigned halfLower = range.first * 0.5;
+        return 2 * (halfLower + rand() % (halfUpper - halfLower + 1));
+    }
+}
+
+unsigned
+SIPAccount::generateAudioPort() const
+{
+    return getRandomEvenNumber(audioPortRange_);
+}
+
+#ifdef SFL_VIDEO
+unsigned
+SIPAccount::generateVideoPort() const
+{
+    return getRandomEvenNumber(videoPortRange_);
+}
+#endif
diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h
index f1d5c81ec2d26172740a3205c327680e557fca0c..c4b3c520c77e9e22805c622397c5db2761a2e451 100644
--- a/daemon/src/sip/sipaccount.h
+++ b/daemon/src/sip/sipaccount.h
@@ -199,7 +199,7 @@ class SIPAccount : public Account {
 
 
         const pjsip_cred_info* getCredInfo() const {
-            return &(*cred_.begin());
+            return cred_.data();
         }
 
         /**
@@ -525,7 +525,12 @@ class SIPAccount : public Account {
          */
         SIPPresence * getPresence();
 
-private:
+        unsigned generateAudioPort() const;
+#ifdef SFL_VIDEO
+        unsigned generateVideoPort() const;
+#endif
+
+    private:
         NON_COPYABLE(SIPAccount);
 
         bool fullMatch(const std::string &username, const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
@@ -553,9 +558,10 @@ private:
         void initTlsConfiguration();
 
         /**
-         * Display the list of ciphers currently supported on the
+         * PJSIP aborts if the string length of our cipher list is too
+         * great, so this function forces our cipher list to fit this constraint.
          */
-        void displayCipherSuite();
+        void trimCiphers();
 #endif
 
         /**
@@ -642,9 +648,9 @@ private:
         pjsip_tls_setting tlsSetting_;
 
         /**
-         * Allocate a static array to be used by pjsip to store the supported ciphers on this system.
+         * Allocate a vector to be used by pjsip to store the supported ciphers on this system.
          */
-        CipherArray ciphers;
+        CipherArray ciphers_;
 
         /**
          * The STUN server name (hostname)
@@ -777,6 +783,17 @@ private:
          */
         SIPPresence * presence_;
 
+        /*
+         * Port range for audio RTP ports
+         */
+        std::pair<unsigned, unsigned> audioPortRange_;
+
+#ifdef SFL_VIDEO
+        /**
+         * Port range for video RTP ports
+         */
+        std::pair<unsigned, unsigned> videoPortRange_;
+#endif
 };
 
 #endif
diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp
index 904daadcf5ce32a9a7b7c9d4c41e2d8a23499bd8..5a1b7a0eb992eb8f714506fd4b2eb4f78ee3c415 100644
--- a/daemon/src/sip/sipcall.cpp
+++ b/daemon/src/sip/sipcall.cpp
@@ -36,7 +36,7 @@
 #include "sdp.h"
 #include "manager.h"
 #ifdef SFL_VIDEO
-#include "dbus/video_controls.h"
+#include "client/video_controls.h"
 #endif
 
 namespace {
@@ -51,7 +51,7 @@ SIPCall::SIPCall(const std::string& id, Call::CallType type,
     , audiortp_(this)
 #ifdef SFL_VIDEO
     // The ID is used to associate video streams to calls
-    , videortp_(id, Manager::instance().getDbusManager()->getVideoControls()->getSettings())
+    , videortp_(id, Manager::instance().getClient()->getVideoControls()->getSettings())
 #endif
     , pool_(pj_pool_create(&caching_pool->factory, id.c_str(), INITIAL_SIZE, INCREMENT_SIZE, NULL))
     , local_sdp_(new Sdp(pool_))
diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp
index 5e2729781ea3770c72613a3c3136e8cdfd05ff4b..85f7c19bf2cf3142d17916d97d4899594d16df50 100644
--- a/daemon/src/sip/siptransport.cpp
+++ b/daemon/src/sip/siptransport.cpp
@@ -29,6 +29,10 @@
  *  as that of the covered work.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <map>
 
 #include <pjsip.h>
@@ -40,6 +44,7 @@
 #include <netinet/in.h>
 #include <arpa/nameser.h>
 #include <resolv.h>
+#include <unistd.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
@@ -59,8 +64,7 @@
 #include "pjsip/sip_transport_tls.h"
 #endif
 
-#include "dbus/dbusmanager.h"
-#include "dbus/configurationmanager.h"
+#include "client/configurationmanager.h"
 
 static const char * const DEFAULT_INTERFACE = "default";
 static const char * const ANY_HOSTS = "0.0.0.0";
@@ -474,9 +478,8 @@ SipTransport::getSTUNAddresses(const SIPAccount &account,
                 &serverName, port, &serverName, port, &result[0]) != PJ_SUCCESS)
         throw std::runtime_error("Can't contact STUN server");
 
-    for (std::vector<pj_sockaddr_in>::const_iterator it = result.begin();
-            it != result.end(); ++it)
-        WARN("STUN PORTS: %ld", pj_ntohs(it->sin_port));
+    for (const auto & it : result)
+        WARN("STUN PORTS: %ld", pj_ntohs(it.sin_port));
 
     return result;
 }
@@ -484,11 +487,15 @@ SipTransport::getSTUNAddresses(const SIPAccount &account,
 
 pjsip_transport *SipTransport::createStunTransport(SIPAccount &account)
 {
+#if HAVE_DBUS
 #define RETURN_IF_STUN_FAIL(A, M, ...) \
     if (!(A)) { \
         ERROR(M, ##__VA_ARGS__); \
-        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure(account.getAccountID()); \
+        Manager::instance().getClient()->getConfigurationManager()->stunStatusFailure(account.getAccountID()); \
         return NULL; }
+#else /* HAVE_DBUS */
+#define RETURN_IF_STUN_FAIL(A, M, ...)
+#endif /* HAVE_DBUS */
 
     pj_str_t serverName = account.getStunServerName();
     pj_uint16_t port = account.getStunPort();
@@ -511,7 +518,8 @@ pjsip_transport *SipTransport::createStunTransport(SIPAccount &account)
     if (pjstun_get_mapped_addr(&cp_->factory, 1, &sock, &serverName, port, &serverName, port, &pub_addr) != PJ_SUCCESS) {
         ERROR("Can't contact STUN server");
         pj_sock_close(sock);
-        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure(account.getAccountID());
+
+        Manager::instance().getClient()->getConfigurationManager()->stunStatusFailure(account.getAccountID());
         return NULL;
     }
 
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index 0a2865c9017ffdfde3a63e7655e4638d5dac8604..0d413698b5669a8ba3e8d9bb38a85997762427f0 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -52,9 +52,6 @@
 #endif
 #include "array_size.h"
 
-#include "dbus/dbusmanager.h"
-#include "dbus/callmanager.h"
-#include "dbus/configurationmanager.h"
 
 #if HAVE_INSTANT_MESSAGING
 #include "im/instant_messaging.h"
@@ -64,9 +61,13 @@
 
 #ifdef SFL_VIDEO
 #include "video/video_rtp_session.h"
-#include "dbus/video_controls.h"
+#include "client/video_controls.h"
 #endif
 
+#include "client/client.h"
+#include "client/callmanager.h"
+#include "client/configurationmanager.h"
+
 #include "pjsip/sip_endpoint.h"
 #include "pjsip/sip_uri.h"
 #include "pjnath.h"
@@ -123,6 +124,11 @@ void registration_cb(pjsip_regc_cbparam *param);
 pj_bool_t transaction_request_cb(pjsip_rx_data *rdata);
 pj_bool_t transaction_response_cb(pjsip_rx_data *rdata) ;
 
+#ifdef __ANDROID__
+void showLog(int level, const char *data, int len);
+void showMsg(const char *format, ...);
+#endif
+
 void transfer_client_cb(pjsip_evsub *sub, pjsip_event *event);
 
 /**
@@ -193,6 +199,26 @@ pj_bool_t transaction_response_cb(pjsip_rx_data *rdata)
     return PJ_FALSE;
 }
 
+#ifdef __ANDROID__
+void showMsg(const char *format, ...)
+{
+    va_list arg;
+
+    va_start(arg, format);
+    __android_log_vprint(ANDROID_LOG_INFO, "apjsua", format, arg);
+    //vsnprintf(app_var.out_buf, sizeof(app_var.out_buf), format, arg);
+    va_end(arg);
+
+    /* pj_sem_post(app_var.output_sem);
+    pj_sem_wait(app_var.out_print_sem); */
+}
+
+void showLog(int level, const char *data, int len)
+{
+    showMsg("%s", data);
+}
+#endif
+
 void updateSDPFromSTUN(SIPCall &call, SIPAccount &account, const SipTransport &transport)
 {
     std::vector<long> socketDescriptors(call.getAudioRtp().getSocketDescriptors());
@@ -210,9 +236,20 @@ void updateSDPFromSTUN(SIPCall &call, SIPAccount &account, const SipTransport &t
     }
 }
 
+void
+addContactHeader(const std::string &contactStr, pjsip_tx_data *tdata)
+{
+    pj_str_t pjContact = pj_str((char*) contactStr.c_str());
+
+    pjsip_contact_hdr *contact = pjsip_contact_hdr_create(tdata->pool);
+    contact->uri = pjsip_parse_uri(tdata->pool, pjContact.ptr,
+                                   pjContact.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) contact);
+}
 
 pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 {
+
     if (!rdata or !rdata->msg_info.msg) {
         ERROR("rx_data is NULL");
         return PJ_FALSE;
@@ -424,11 +461,30 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
         if (pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL, &tdata) == PJ_SUCCESS && tdata)
             pjsip_inv_send_msg(replaced_inv, tdata);
     } else { // Proceed with normal call flow
-        if (pjsip_inv_initial_answer(call->inv, rdata, PJSIP_SC_RINGING, NULL, NULL, &tdata) != PJ_SUCCESS) {
+        if (pjsip_inv_initial_answer(call->inv, rdata, PJSIP_SC_TRYING, NULL, NULL, &tdata) != PJ_SUCCESS) {
             ERROR("Could not answer invite");
             delete call;
             return PJ_FALSE;
         }
+
+        if (pjsip_inv_send_msg(call->inv, tdata) != PJ_SUCCESS) {
+            ERROR("Could not send msg for invite");
+            delete call;
+            return PJ_FALSE;
+        }
+
+        call->setConnectionState(Call::TRYING);
+
+        if (pjsip_inv_answer(call->inv, PJSIP_SC_RINGING, NULL, NULL, &tdata) != PJ_SUCCESS) {
+            ERROR("Could not answer invite");
+            delete call;
+            return PJ_FALSE;
+        }
+
+        // contactStr must stay in scope as long as tdata
+        const std::string contactStr(account->getContactHeader());
+        addContactHeader(contactStr, tdata);
+
         if (pjsip_inv_send_msg(call->inv, tdata) != PJ_SUCCESS) {
             ERROR("Could not send msg for invite");
             delete call;
@@ -440,7 +496,6 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
         Manager::instance().incomingCall(*call, account_id);
         SIPVoIPLink::instance()->addSipCall(call);
     }
-
     return PJ_FALSE;
 }
 } // end anonymous namespace
@@ -462,6 +517,7 @@ SIPVoIPLink::SIPVoIPLink() : sipTransport(endpt_, cp_, pool_), sipAccountMap_(),
 #endif
   , presenceState()
 {
+
 #define TRY(ret) do { \
     if (ret != PJ_SUCCESS) \
     throw VoipLinkException(#ret " failed"); \
@@ -476,8 +532,12 @@ SIPVoIPLink::SIPVoIPLink() : sipTransport(endpt_, cp_, pool_), sipAccountMap_(),
     srand(time(NULL)); // to get random number for RANDOM_PORT
 
     TRY(pj_init());
+
     TRY(pjlib_util_init());
 
+#ifdef __ANDROID__
+    setSipLogger();
+#endif
     setSipLogLevel();
     TRY(pjnath_init());
 
@@ -593,8 +653,10 @@ SIPVoIPLink::~SIPVoIPLink()
 SIPVoIPLink* SIPVoIPLink::instance()
 {
     assert(!destroyed_);
-    if (!instance_)
+    if (!instance_) {
+        DEBUG("creating SIPVoIPLink instance");
         instance_ = new SIPVoIPLink;
+    }
     return instance_;
 }
 
@@ -612,10 +674,10 @@ SIPVoIPLink::getAccountIdFromNameAndServer(const std::string &userName,
     DEBUG("username = %s, server = %s", userName.c_str(), server.c_str());
     // Try to find the account id from username and server name by full match
 
-    for (AccountMap::const_iterator iter = sipAccountMap_.begin(); iter != sipAccountMap_.end(); ++iter) {
-        SIPAccount *account = static_cast<SIPAccount*>(iter->second);
+    for (const auto &item : sipAccountMap_) {
+        SIPAccount *account = static_cast<SIPAccount*>(item.second);
         if (account and account->matches(userName, server, endpt_, pool_))
-            return iter->first;
+            return item.first;
     }
 
     DEBUG("Username %s or server %s doesn't match any account, using IP2IP", userName.c_str(), server.c_str());
@@ -627,7 +689,7 @@ void SIPVoIPLink::setSipLogLevel()
     char *envvar = getenv(SIPLOGLEVEL);
     int level = 0;
 
-    if(envvar != NULL) {
+    if (envvar != NULL) {
         std::string loglevel = envvar;
 
         if ( ! (std::istringstream(loglevel) >> level) ) level = 0;
@@ -636,10 +698,22 @@ void SIPVoIPLink::setSipLogLevel()
         level = level < 0 ? 0 : level;
     }
 
+#ifdef __ANDROID__
+    level = 6;
+#endif
+
     // From 0 (min) to 6 (max)
     pj_log_set_level(level);
 }
 
+#ifdef __ANDROID__
+void SIPVoIPLink::setSipLogger()
+{
+    static pj_log_func *currentFunc = (pj_log_func*) pj_log_get_log_func();
+    pj_log_set_log_func(&showLog);
+}
+#endif
+
 // Called from EventThread::run (not main thread)
 bool SIPVoIPLink::getEvent()
 {
@@ -696,6 +770,7 @@ void SIPVoIPLink::sendRegister(Account *a)
     std::string contact = account->getContactHeader();
     pj_str_t pjContact = pj_str((char*) contact.c_str());
 
+
     if (account->transport_) {
         if (account->isStunEnabled()) {
             DEBUG("Setting VIA sent-by to %s:%u", account->transport_->local_name.host.ptr, account->transport_->local_name.port);
@@ -1035,14 +1110,9 @@ SIPVoIPLink::hangup(const std::string& id, int reason)
     if (pjsip_inv_end_session(inv, status, NULL, &tdata) != PJ_SUCCESS || !tdata)
         return;
 
-    // add contact header
+    // contactStr must stay in scope as long as tdata
     const std::string contactStr(account->getContactHeader());
-    pj_str_t pjContact = pj_str((char*) contactStr.c_str());
-
-    pjsip_contact_hdr *contact = pjsip_contact_hdr_create(tdata->pool);
-    contact->uri = pjsip_parse_uri(tdata->pool, pjContact.ptr,
-                                   pjContact.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
-    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) contact);
+    addContactHeader(contactStr, tdata);
 
     if (pjsip_inv_send_msg(inv, tdata) != PJ_SUCCESS)
         return;
@@ -1125,14 +1195,13 @@ SIPVoIPLink::offhold(const std::string& id)
         std::vector<sfl::AudioCodec*> sessionMedia;
         sdpSession->getSessionAudioMedia(sessionMedia);
         std::vector<sfl::AudioCodec*> audioCodecs;
-        for (std::vector<sfl::AudioCodec*>::const_iterator i = sessionMedia.begin();
-             i != sessionMedia.end(); ++i) {
+        for (auto &i : sessionMedia) {
 
-            if (!*i)
+            if (!i)
                 continue;
 
             // Create a new instance for this codec
-            sfl::AudioCodec* ac = Manager::instance().audioCodecFactory.instantiateCodec((*i)->getPayloadType());
+            sfl::AudioCodec* ac = Manager::instance().audioCodecFactory.instantiateCodec(i->getPayloadType());
 
             if (ac == NULL)
                 throw VoipLinkException("Could not instantiate codec");
@@ -1199,9 +1268,8 @@ SIPVoIPLink::clearSipCallMap()
 {
     sfl::ScopedLock m(sipCallMapMutex_);
 
-    for (SipCallMap::const_iterator iter = sipCallMap_.begin();
-            iter != sipCallMap_.end(); ++iter)
-        delete iter->second;
+    for (const auto &item : sipCallMap_)
+        delete item.second;
 
     sipCallMap_.clear();
 }
@@ -1251,7 +1319,7 @@ SIPVoIPLink::getSipCall(const std::string& id)
     if (iter != sipCallMap_.end())
         return iter->second;
     else {
-        ERROR("No SIP call with ID %s", id.c_str());
+        DEBUG("No SIP call with ID %s", id.c_str());
         return NULL;
     }
 }
@@ -1674,7 +1742,8 @@ void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *ev)
         if (statusCode) {
             const pj_str_t * description = pjsip_get_status_text(statusCode);
             std::string desc(description->ptr, description->slen);
-            CallManager *cm = Manager::instance().getDbusManager()->getCallManager();
+
+            CallManager *cm = Manager::instance().getClient()->getCallManager();
             cm->sipCallStateChanged(call->getCallId(), desc, statusCode);
         }
     }
@@ -1839,7 +1908,12 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
     // Update internal field for
     sdpSession->setMediaTransportInfoFromRemoteSdp();
 
-    call->getAudioRtp().updateDestinationIpAddress();
+    try {
+        call->getAudioRtp().updateDestinationIpAddress();
+    } catch (const AudioRtpFactoryException &e) {
+        ERROR("%s", e.what());
+    }
+
     call->getAudioRtp().setDtmfPayloadType(sdpSession->getTelephoneEventType());
 #ifdef SFL_VIDEO
     Manager::instance().getVideoControls()->stopPreview();
@@ -1870,10 +1944,10 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
                 call->getAudioRtp().setRemoteCryptoInfo(sdesnego);
             } catch (...) {}
 
-            Manager::instance().getDbusManager()->getCallManager()->secureSdesOn(call->getCallId());
+            Manager::instance().getClient()->getCallManager()->secureSdesOn(call->getCallId());
         } else {
             ERROR("SDES negotiation failure");
-            Manager::instance().getDbusManager()->getCallManager()->secureSdesOff(call->getCallId());
+            Manager::instance().getClient()->getCallManager()->secureSdesOff(call->getCallId());
         }
     }
     else {
@@ -1907,10 +1981,10 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
         Manager::instance().startAudioDriverStream();
 
         std::vector<AudioCodec*> audioCodecs;
-        for (std::vector<sfl::AudioCodec*>::const_iterator i = sessionMedia.begin(); i != sessionMedia.end(); ++i) {
-            if (!*i)
+        for (const auto &i : sessionMedia) {
+            if (!i)
                 continue;
-            const int pl = (*i)->getPayloadType();
+            const int pl = i->getPayloadType();
 
             sfl::AudioCodec *ac = Manager::instance().audioCodecFactory.instantiateCodec(pl);
             if (!ac)
@@ -2128,7 +2202,8 @@ void registration_cb(pjsip_regc_cbparam *param)
 
     if (param->code && description) {
         std::string state(description->ptr, description->slen);
-        Manager::instance().getDbusManager()->getCallManager()->registrationStateChanged(accountID, state, param->code);
+
+        Manager::instance().getClient()->getCallManager()->registrationStateChanged(accountID, state, param->code);
         std::pair<int, std::string> details(param->code, state);
         // TODO: there id a race condition for this ressource when closing the application
         account->setRegistrationStateDetailed(details);
@@ -2298,16 +2373,6 @@ void transfer_client_cb(pjsip_evsub *sub, pjsip_event *event)
     }
 }
 
-namespace {
-    // returns even number in range [lower, upper]
-    unsigned int getRandomEvenNumber(int lower, int upper)
-    {
-        const unsigned halfUpper = upper * 0.5;
-        const unsigned halfLower = lower * 0.5;
-        return 2 * (halfLower + rand() % (halfUpper - halfLower + 1));
-    }
-}
-
 void setCallMediaLocal(SIPCall* call, const std::string &localIP)
 {
     std::string account_id(call->getAccountId());
@@ -2318,7 +2383,7 @@ void setCallMediaLocal(SIPCall* call, const std::string &localIP)
     // Reference: http://www.cs.columbia.edu/~hgs/rtp/faq.html#ports
       // We only want to set ports to new values if they haven't been set
     if (call->getLocalAudioPort() == 0) {
-        const unsigned callLocalAudioPort = getRandomEvenNumber(16384, 32766);
+        const unsigned callLocalAudioPort = account->generateAudioPort();
         call->setLocalAudioPort(callLocalAudioPort);
         call->getLocalSDP()->setLocalPublishedAudioPort(callLocalAudioPort);
     }
@@ -2330,7 +2395,7 @@ void setCallMediaLocal(SIPCall* call, const std::string &localIP)
         // https://projects.savoirfairelinux.com/issues/17498
         unsigned int callLocalVideoPort;
         do
-            callLocalVideoPort = getRandomEvenNumber(49152, 65534);
+            callLocalVideoPort = account->generateVideoPort();
         while (call->getLocalAudioPort() == callLocalVideoPort);
 
         call->setLocalVideoPort(callLocalVideoPort);
diff --git a/daemon/src/sip/sipvoiplink.h b/daemon/src/sip/sipvoiplink.h
index 224dc51868e4940d153d04afac0d224005aa86aa..8c2db215b60b669ee232c023101eff6152926302 100644
--- a/daemon/src/sip/sipvoiplink.h
+++ b/daemon/src/sip/sipvoiplink.h
@@ -91,6 +91,10 @@ class SIPVoIPLink : public VoIPLink {
          */
         static void setSipLogLevel();
 
+#ifdef __ANDROID__
+        static void setSipLogger();
+#endif
+
         /**
          * Event listener. Each event send by the call manager is received and handled from here
          */
diff --git a/daemon/src/video/libav_utils.cpp b/daemon/src/video/libav_utils.cpp
index a70342cad1ab8be9f51cb2022d5a89c46a48a4f4..99b18a6589d6dc6175770c4b7ef386f05e4742cb 100644
--- a/daemon/src/video/libav_utils.cpp
+++ b/daemon/src/video/libav_utils.cpp
@@ -58,11 +58,11 @@ void findInstalledVideoCodecs()
         if (p->type == AVMEDIA_TYPE_VIDEO)
             libav_codecs.push_back(p->name);
 
-    for (map<string, string>::const_iterator it = encoders_.begin(); it != encoders_.end(); ++it) {
-        if (std::find(libav_codecs.begin(), libav_codecs.end(), it->second) != libav_codecs.end())
-            installed_video_codecs_.push_back(it->first);
+    for (const auto &it : encoders_) {
+        if (std::find(libav_codecs.begin(), libav_codecs.end(), it.second) != libav_codecs.end())
+            installed_video_codecs_.push_back(it.first);
         else
-            ERROR("Didn't find \"%s\" encoder", it->second.c_str());
+            ERROR("Didn't find \"%s\" encoder", it.second.c_str());
     }
 }
 
@@ -160,15 +160,14 @@ getDefaultCodecs()
     const char * const DEFAULT_BITRATE = "400";
     sfl_avcodec_init();
     std::vector<std::map<std::string, std::string> > result;
-    for (std::vector<std::string>::const_iterator iter = installed_video_codecs_.begin();
-         iter != installed_video_codecs_.end(); ++iter) {
+    for (const auto &item : installed_video_codecs_) {
         std::map<std::string, std::string> codec;
         // FIXME: get these keys from proper place
-        codec["name"] = *iter;
+        codec["name"] = item;
         codec["bitrate"] = DEFAULT_BITRATE;
         codec["enabled"] = "true";
         // FIXME: make a nicer version of this
-        if (*iter == "H264")
+        if (item == "H264")
             codec["parameters"] = DEFAULT_H264_PROFILE_LEVEL_ID;
         result.push_back(codec);
     }
diff --git a/daemon/src/video/shm_sink.cpp b/daemon/src/video/shm_sink.cpp
index ff48b2457637b9d349906a502ec1d9cde07c5110..ab3c4f5937a9727cd57663aaee712f0199a729b9 100644
--- a/daemon/src/video/shm_sink.cpp
+++ b/daemon/src/video/shm_sink.cpp
@@ -183,7 +183,7 @@ void SHMSink::render(const std::vector<unsigned char> &data)
     if (!resize_area(sizeof(SHMHeader) + data.size()))
         return;
 
-    memcpy(shm_area_->data, &(*data.begin()), data.size());
+    memcpy(shm_area_->data, data.data(), data.size());
     shm_area_->buffer_size = data.size();
     shm_area_->buffer_gen++;
     sem_post(&shm_area_->notification);
diff --git a/daemon/src/video/socket_pair.cpp b/daemon/src/video/socket_pair.cpp
index 86769698d56fb992b083f8e2d851e0c137dbcd18..c670e5da0ede87cc0ca6b2caeab10c80a383bbba 100644
--- a/daemon/src/video/socket_pair.cpp
+++ b/daemon/src/video/socket_pair.cpp
@@ -181,7 +181,6 @@ void
 SocketPair::openSockets(const char *uri, int local_rtp_port)
 {
     char hostname[256];
-    char buf[1024];
     char path[1024];
 
     int rtp_port;
diff --git a/daemon/src/video/test/Makefile.am b/daemon/src/video/test/Makefile.am
index b5138618eb80f879df8137e3ebf943ddc41b0fef..c1bf99db9301b0f34b8081528dc72719194b460d 100644
--- a/daemon/src/video/test/Makefile.am
+++ b/daemon/src/video/test/Makefile.am
@@ -17,6 +17,6 @@ test_v4l2_LDADD=$(top_builddir)/src/libsflphone.la $(top_builddir)/src/video/lib
 
 test_shm_SOURCES=test_shm.cpp shm_src.cpp shm_src.h
 test_shm_LDADD=$(top_builddir)/src/libsflphone.la $(top_builddir)/src/video/libvideo.la $(YAML_LIBS)
-test_shm_CXXFLAGS=$(AM_CXXFLAGS) -std=c++0x
+test_shm_CXXFLAGS=$(AM_CXXFLAGS)
 
 AM_CXXFLAGS=-I$(top_builddir)/src/video -I$(top_builddir)/src
diff --git a/daemon/src/video/test/test_shm.cpp b/daemon/src/video/test/test_shm.cpp
index 199166b7a84a3e3e972ec49bab526d444f75da45..1ac94610ac9486d75467a017755db0fdb2ea8086 100644
--- a/daemon/src/video/test/test_shm.cpp
+++ b/daemon/src/video/test/test_shm.cpp
@@ -80,12 +80,12 @@ void run_client()
         return;
 
     // initialize destination string to 0's
-    std::string dest(sizeof(test_data), 0);
-    const std::string test_data_str(test_data, sizeof(test_data));
+    std::vector<char> dest(sizeof(test_data), 0);
+    const std::vector<char> test_data_str(test_data, test_data + sizeof(test_data));
     assert(test_data_str.size() == 27);
     assert(dest.size() == test_data_str.size());
     while (not done and dest != test_data_str) {
-        src.render(&(*dest.begin()), dest.size());
+        src.render(dest.data(), dest.size());
         usleep(1000);
     }
     src.stop();
diff --git a/daemon/src/video/video_receive_thread.cpp b/daemon/src/video/video_receive_thread.cpp
index 31ca3337a0f565be742f2d9e2a4aa74793f59324..6b41a893f85bb7af97c659850a3f3d6250e488db 100644
--- a/daemon/src/video/video_receive_thread.cpp
+++ b/daemon/src/video/video_receive_thread.cpp
@@ -31,7 +31,7 @@
 
 #include "video_receive_thread.h"
 #include "socket_pair.h"
-#include "dbus/video_controls.h"
+#include "client/video_controls.h"
 #include "check.h"
 #include "packet_handle.h"
 
@@ -42,6 +42,7 @@ extern "C" {
 #include <libavdevice/avdevice.h>
 #include <libswscale/swscale.h>
 }
+#include <unistd.h>
 #include <map>
 
 #include "manager.h"
diff --git a/daemon/src/video/video_send_thread.cpp b/daemon/src/video/video_send_thread.cpp
index 74566b311c3ba700ad505358f66c7bed9d0314d6..f15b7d25105ac03da3fae459e19a2afd25569748 100644
--- a/daemon/src/video/video_send_thread.cpp
+++ b/daemon/src/video/video_send_thread.cpp
@@ -30,7 +30,7 @@
 
 #include "video_send_thread.h"
 #include "socket_pair.h"
-#include "dbus/video_controls.h"
+#include "client/video_controls.h"
 #include "packet_handle.h"
 #include "check.h"
 
@@ -62,7 +62,7 @@ void VideoSendThread::print_sdp()
     /* theora sdp can be huge */
     const size_t sdp_size = outputCtx_->streams[0]->codec->extradata_size + 2048;
     std::string sdp(sdp_size, 0);
-    av_sdp_create(&outputCtx_, 1, &(*sdp.begin()), sdp_size);
+    av_sdp_create(&outputCtx_, 1, &sdp[0], sdp_size);
     std::istringstream iss(sdp);
     string line;
     sdp_ = "";
diff --git a/daemon/src/video/video_v4l2.cpp b/daemon/src/video/video_v4l2.cpp
index 04e594c1dc4777d65360290d2f51569a93e10b88..343a5d615cad2c86ce017c525f8e9991724f8041 100644
--- a/daemon/src/video/video_v4l2.cpp
+++ b/daemon/src/video/video_v4l2.cpp
@@ -121,10 +121,9 @@ static const unsigned pixelformats_supported[] = {
 namespace {
 unsigned int pixelformat_score(unsigned pixelformat)
 {
-    size_t n = sizeof pixelformats_supported / sizeof *pixelformats_supported;
-    for (unsigned int i = 0; i < n ; ++i)
-        if (pixelformats_supported[i] == pixelformat)
-            return i;
+    for (const auto &item : pixelformats_supported)
+        if (item == pixelformat)
+            return item;
 
     return UINT_MAX - 1;
 }
@@ -137,9 +136,9 @@ vector<string> VideoV4l2Size::getRateList()
 {
     vector<string> v;
 
-    for (vector<float>::const_iterator i = rates_.begin() ; i != rates_.end(); ++i) {
+    for (const auto &item : rates_) {
         std::stringstream ss;
-        ss << *i;
+        ss << item;
         v.push_back(ss.str());
     }
 
@@ -201,9 +200,9 @@ vector<string> VideoV4l2Channel::getSizeList() const
 {
     vector<string> v;
 
-    for (vector<VideoV4l2Size>::const_iterator itr = sizes_.begin(); itr != sizes_.end(); ++itr) {
+    for (const auto &item : sizes_) {
         std::stringstream ss;
-        ss << itr->width << "x" << itr->height;
+        ss << item.width << "x" << item.height;
         v.push_back(ss.str());
     }
 
@@ -309,11 +308,11 @@ void VideoV4l2Channel::getFormat(int fd)
 
 VideoV4l2Size VideoV4l2Channel::getSize(const string &name) const
 {
-    for (vector<VideoV4l2Size>::const_iterator i = sizes_.begin(); i != sizes_.end(); ++i) {
+    for (const auto &item : sizes_) {
         std::stringstream ss;
-        ss << i->width << "x" << i->height;
+        ss << item.width << "x" << item.height;
         if (ss.str() == name)
-            return *i;
+            return item;
     }
 
     // fallback to last size
@@ -354,8 +353,8 @@ vector<string> VideoV4l2Device::getChannelList() const
 {
     vector<string> v;
 
-    for (vector<VideoV4l2Channel>::const_iterator itr = channels_.begin(); itr != channels_.end(); ++itr)
-        v.push_back(itr->name);
+    for (const auto &itr : channels_)
+        v.push_back(itr.name);
 
     return v;
 }
@@ -363,9 +362,9 @@ vector<string> VideoV4l2Device::getChannelList() const
 const VideoV4l2Channel &
 VideoV4l2Device::getChannel(const string &name) const
 {
-    for (vector<VideoV4l2Channel>::const_iterator itr = channels_.begin(); itr != channels_.end(); ++itr)
-        if (itr->name == name)
-            return *itr;
+    for (const auto &item : channels_)
+        if (item.name == name)
+            return item;
 
     return channels_.back();
 }
diff --git a/daemon/src/video/video_v4l2_list.cpp b/daemon/src/video/video_v4l2_list.cpp
index 9e592bba7ca94f26cf80b92c2ca6cb7c7aa25173..8cdc806554e926014436924fbb9d20845fdb2ce1 100644
--- a/daemon/src/video/video_v4l2_list.cpp
+++ b/daemon/src/video/video_v4l2_list.cpp
@@ -34,6 +34,7 @@
 #include <stdexcept> // for std::runtime_error
 #include <sstream>
 #include <algorithm>
+#include <unistd.h>
 
 #include "logger.h"
 #include "scoped_lock.h"
@@ -51,7 +52,7 @@ extern "C" {
 
 #include "video_v4l2_list.h"
 #include "manager.h"
-#include "dbus/video_controls.h"
+#include "client/video_controls.h"
 
 namespace sfl_video {
 
@@ -194,8 +195,8 @@ namespace {
     void giveUniqueName(VideoV4l2Device &dev, const vector<VideoV4l2Device> &devices)
     {
 start:
-        for (size_t i = 0; i < devices.size(); ++i) {
-            if (dev.name == devices[i].name) {
+        for (auto &item : devices) {
+            if (dev.name == item.name) {
                 size_t sharp;
                 int num = getNumber(dev.name, &sharp);
                 if (num < 0) // not numbered
@@ -287,7 +288,7 @@ void VideoV4l2ListThread::delDevice(const string &node)
 {
     ScopedLock lock(mutex_);
 
-    for (std::vector<VideoV4l2Device>::iterator itr = devices_.begin(); itr != devices_.end(); ++itr) {
+    for (auto itr = devices_.begin(); itr != devices_.end(); ++itr) {
         if (itr->device == node) {
             devices_.erase(itr);
             Manager::instance().getVideoControls()->deviceEvent();
@@ -351,8 +352,8 @@ vector<string> VideoV4l2ListThread::getDeviceList()
     ScopedLock lock(mutex_);
     vector<string> v;
 
-    for (std::vector<VideoV4l2Device>::iterator itr = devices_.begin(); itr != devices_.end(); ++itr)
-       v.push_back(itr->name.empty() ? itr->device : itr->name);
+    for (const auto &itr : devices_)
+       v.push_back(itr.name.empty() ? itr.device : itr.name);
 
     return v;
 }
diff --git a/daemon/test/Makefile.am b/daemon/test/Makefile.am
index 3c9fc09df60f82dd2733f5c0313a4cd6626da643..e945b75282a718498dfa23df187b4d8e7cc87b4b 100644
--- a/daemon/test/Makefile.am
+++ b/daemon/test/Makefile.am
@@ -35,7 +35,9 @@ test_SOURCES = constants.h \
 			   resamplertest.h \
 			   resamplertest.cpp \
 			   hooktest.h \
-			   hooktest.cpp
+			   hooktest.cpp \
+			   audiobuffertest.h \
+			   audiobuffertest.cpp
 
 if BUILD_SDES
 test_SOURCES+=sdesnegotiatortest.h \
diff --git a/daemon/test/audiobuffertest.cpp b/daemon/test/audiobuffertest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b6143fe2624dc9a42c6eaf2acf06cb84fddf2626
--- /dev/null
+++ b/daemon/test/audiobuffertest.cpp
@@ -0,0 +1,107 @@
+/*
+ *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ *  Author: Adrien Beraud <adrienberaud@gmail.com>
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#include <string>
+#include "audiobuffertest.h"
+#include "audio/audiobuffer.h"
+#include "audio/ringbuffer.h"
+#include "logger.h"
+#include "test_utils.h"
+
+void AudioBufferTest::testAudioBufferConstructors()
+{
+    TITLE();
+
+    SFLAudioSample test_samples1[] = {};
+    SFLAudioSample test_samples2[] = {10, 11, 12, 13, 14, 15, 16, 17};
+
+    AudioBuffer empty_buf;
+    CPPUNIT_ASSERT(empty_buf.samples() == 0);
+    CPPUNIT_ASSERT(empty_buf.channels() == 1);
+    CPPUNIT_ASSERT(empty_buf.getChannel(0)->size() == 0);
+
+    AudioBuffer test_buf1(8, 2);
+    CPPUNIT_ASSERT(test_buf1.samples() == 8);
+    CPPUNIT_ASSERT(test_buf1.channels() == 2);
+    CPPUNIT_ASSERT(test_buf1.getChannel(0)->size() == 8);
+    CPPUNIT_ASSERT(test_buf1.getChannel(1)->size() == 8);
+    CPPUNIT_ASSERT(test_buf1.getChannel(2) == NULL);
+
+    AudioBuffer test_buf2(test_samples1, 0, 0);
+    CPPUNIT_ASSERT(test_buf2.samples() == 0);
+    CPPUNIT_ASSERT(test_buf2.channels() == 1);
+    CPPUNIT_ASSERT(test_buf2.getChannel(0)->size() == 0);
+
+    AudioBuffer test_buf3(test_samples2, 4, 2);
+    CPPUNIT_ASSERT(test_buf3.samples() == 4);
+    CPPUNIT_ASSERT(test_buf3.channels() == 2);
+    CPPUNIT_ASSERT(test_buf3.getChannel(0)->size() == 4);
+}
+
+void AudioBufferTest::testAudioBufferMix()
+{
+    TITLE();
+
+    SFLAudioSample test_samples1[] = {18, 19, 20, 21, 22, 23, 24, 25};
+    SFLAudioSample test_samples2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18};
+
+    AudioBuffer test_buf1(test_samples1, 4, 2);
+    CPPUNIT_ASSERT(test_buf1.channels() == 2);
+    test_buf1.setChannelNum(1);
+    CPPUNIT_ASSERT(test_buf1.channels() == 1);
+    test_buf1.setChannelNum(2);
+    CPPUNIT_ASSERT(test_buf1.channels() == 2);
+    CPPUNIT_ASSERT(test_buf1.getChannel(1)->size() == 4);
+    CPPUNIT_ASSERT((*test_buf1.getChannel(1))[0] == 0);
+    test_buf1.setChannelNum(1);
+    test_buf1.setChannelNum(2, true);
+    CPPUNIT_ASSERT((*test_buf1.getChannel(1))[0] == test_samples1[0]);
+
+    AudioBuffer test_buf2;
+    test_buf2.deinterleave(test_samples2, 3, 3);
+    CPPUNIT_ASSERT((*test_buf2.getChannel(0))[2] == test_samples2[6]);
+    CPPUNIT_ASSERT((*test_buf2.getChannel(1))[1] == test_samples2[4]);
+    CPPUNIT_ASSERT((*test_buf2.getChannel(2))[0] == test_samples2[2]);
+    CPPUNIT_ASSERT(test_buf2.capacity() == 9);
+
+    SFLAudioSample *output = new SFLAudioSample[test_buf2.capacity()];
+    test_buf2.interleave(output);
+    CPPUNIT_ASSERT(std::equal(test_samples2, test_samples2 + sizeof test_samples2 / sizeof *test_samples2, output));
+    //CPPUNIT_ASSERT(std::equal(std::begin(test_samples2), std::end(test_samples2), std::begin(output))); C++11
+
+    test_buf1.mix(test_buf2);
+    CPPUNIT_ASSERT(test_buf1.channels() == 2);
+    CPPUNIT_ASSERT(test_buf1.samples() == 4);
+    CPPUNIT_ASSERT((*test_buf1.getChannel(0))[0] == test_samples1[0]+test_samples2[0]);
+    CPPUNIT_ASSERT((*test_buf1.getChannel(1))[0] == test_samples1[0]+test_samples2[1]);
+}
+
+
+AudioBufferTest::AudioBufferTest() : CppUnit::TestCase("Audio Buffer Tests") {}
diff --git a/daemon/test/audiobuffertest.h b/daemon/test/audiobuffertest.h
new file mode 100644
index 0000000000000000000000000000000000000000..8797a0bbc44ee1a350b9f9e45b499fb5a9a0083d
--- /dev/null
+++ b/daemon/test/audiobuffertest.h
@@ -0,0 +1,70 @@
+/*
+ *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ *  Author: Adrien Beraud <adrienberaud@gmail.com>
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#ifndef AUDIOBUFFER_TEST_
+#define AUDIOBUFFER_TEST_
+
+// Cppunit import
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCaller.h>
+#include <cppunit/TestCase.h>
+#include <cppunit/TestSuite.h>
+
+#include <tr1/memory>
+
+/*
+ * @file audiobuffertest.cpp
+ * @brief       Regroups unit tests related to an audio buffer.
+ */
+
+class AudioBufferTest : public CppUnit::TestCase {
+
+        /*
+         * Use cppunit library macros to add unit test the factory
+         */
+        CPPUNIT_TEST_SUITE(AudioBufferTest);
+        CPPUNIT_TEST(testAudioBufferConstructors);
+        CPPUNIT_TEST(testAudioBufferMix);
+        CPPUNIT_TEST_SUITE_END();
+
+    public:
+
+        AudioBufferTest();
+
+        void testAudioBufferConstructors();
+
+        void testAudioBufferMix();
+};
+
+/* Register our test module */
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(AudioBufferTest, "AudioBufferTest");
+CPPUNIT_TEST_SUITE_REGISTRATION(AudioBufferTest);
+
+#endif  // AUDIOBUFFER_TEST_
diff --git a/daemon/test/instantmessagingtest.cpp b/daemon/test/instantmessagingtest.cpp
index f12df31d78f0951ff82e16345af7f2cc82ecd73f..c07889ed07b9a2d0158a89f3e2101095c00b3a57 100644
--- a/daemon/test/instantmessagingtest.cpp
+++ b/daemon/test/instantmessagingtest.cpp
@@ -192,9 +192,7 @@ void InstantMessagingTest::testXmlUriListParsing()
     sfl::InstantMessaging::UriEntry::iterator iterAttr;
 
     // An iterator over list entries
-    for (sfl::InstantMessaging::UriList::iterator iterEntry = list.begin();
-            iterEntry != list.end(); ++iterEntry) {
-        sfl::InstantMessaging::UriEntry entry = static_cast<sfl::InstantMessaging::UriEntry>(*iterEntry);
+    for (auto &entry : list) {
         iterAttr = entry.find(sfl::IM_XML_URI);
 
         CPPUNIT_ASSERT((iterAttr->second == std::string("sip:alex@example.com")) or
diff --git a/daemon/test/mainbuffertest.cpp b/daemon/test/mainbuffertest.cpp
index f33e927db784f4dd426b4b78239753960b9a9b79..cfc70f6e3e8bfb2dc65a54f0ecf1c5bc043c3d1e 100644
--- a/daemon/test/mainbuffertest.cpp
+++ b/daemon/test/mainbuffertest.cpp
@@ -216,8 +216,11 @@ void MainBufferTest::testRingBufferInt()
 {
     TITLE();
 
-    int testint1 = 12;
-    int testint2 = 13;
+    SFLAudioSample testsample1 = 12;
+    SFLAudioSample testsample2[] = {13, 14, 15, 16, 17, 18};
+
+    AudioBuffer testbuf1(&testsample1, 1); // 1 sample, 1 channel
+    AudioBuffer testbuf2(testsample2, 3, 2); // 3 samples, 2 channels
 
     // test with default ring buffer
     mainbuffer_->createRingBuffer(MainBuffer::DEFAULT_ID);
@@ -228,25 +231,25 @@ void MainBufferTest::testRingBufferInt()
     CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 0);
 
     // add some data
-    test_ring_buffer->put(&testint1, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
+    test_ring_buffer->put(testbuf1); // +1 sample
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
     CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 0);
 
     // add some other data
-    test_ring_buffer->put(&testint2, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 2*sizeof(int));
+    test_ring_buffer->put(testbuf2); // +3 samples
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 4);
     CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 0);
 
-    int testget = (int) NULL;
+    AudioBuffer testget(&testsample1, 1);
 
     // get some data (without any read pointers)
     CPPUNIT_ASSERT(test_ring_buffer->hasNoReadPointers());
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 2*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(MainBuffer::DEFAULT_ID) == 2*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->get(&testget, sizeof(int), MainBuffer::DEFAULT_ID) == 0);
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 2*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(MainBuffer::DEFAULT_ID) == 2*sizeof(int));
-    CPPUNIT_ASSERT(testget == (int) NULL);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 4);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(MainBuffer::DEFAULT_ID) == 4);
+    CPPUNIT_ASSERT(test_ring_buffer->get(testget, MainBuffer::DEFAULT_ID) == 0);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 4);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(MainBuffer::DEFAULT_ID) == 4);
+    CPPUNIT_ASSERT((*testget.getChannel(0))[0] == testsample1);
     CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 0);
 
     // get some data (with a read pointer)
@@ -257,39 +260,39 @@ void MainBufferTest::testRingBufferInt()
     CPPUNIT_ASSERT(test_ring_buffer->getLength(MainBuffer::DEFAULT_ID) == 0);
 
     // add some data
-    test_ring_buffer->put(&testint1, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 2*sizeof(int));
+    test_ring_buffer->put(testbuf1); // +1 sample
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 4);
 
     // add some other data
-    test_ring_buffer->put(&testint2, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 2*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 2*sizeof(int));
+    test_ring_buffer->put(testbuf2); // +3 samples
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 4);
+    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 4);
 
-    CPPUNIT_ASSERT(test_ring_buffer->get(&testget, sizeof(int), MainBuffer::DEFAULT_ID) == sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->get(testget, MainBuffer::DEFAULT_ID) == 1);
 
     // test flush data
-    test_ring_buffer->put(&testint1, sizeof(int));
+    test_ring_buffer->put(testbuf1);
 
     test_ring_buffer->flush(MainBuffer::DEFAULT_ID);
     CPPUNIT_ASSERT(test_ring_buffer->putLength() == 0);
     CPPUNIT_ASSERT(test_ring_buffer->getLength(MainBuffer::DEFAULT_ID) == 0);
     CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 0);
-    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 5*sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 9);
 
     // test flush data
     CPPUNIT_ASSERT(test_ring_buffer->putLength() == 0);
-    test_ring_buffer->put(&testint1, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(MainBuffer::DEFAULT_ID) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 5*sizeof(int));
+    test_ring_buffer->put(testbuf1);
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(MainBuffer::DEFAULT_ID) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 9);
 
-    test_ring_buffer->discard(sizeof(int), MainBuffer::DEFAULT_ID);
+    test_ring_buffer->discard(1, MainBuffer::DEFAULT_ID);
     CPPUNIT_ASSERT(test_ring_buffer->putLength() == 0);
     CPPUNIT_ASSERT(test_ring_buffer->getLength(MainBuffer::DEFAULT_ID) == 0);
     CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 0);
-    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 6*sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 10);
 }
 
 
@@ -299,8 +302,11 @@ void MainBufferTest::testRingBufferNonDefaultID()
 
     std::string test_id = "test_int";
 
-    int testint1 = 12;
-    int testint2 = 13;
+    SFLAudioSample testsample1 = 12;
+    SFLAudioSample testsample2[] = {13, 14, 15, 16, 17, 18};
+
+    AudioBuffer testbuf1(&testsample1, 1); // 1 sample, 1 channel
+    AudioBuffer testbuf2(testsample2, 3, 2); // 3 samples, 2 channels
 
     // test putData, getData with arbitrary read pointer id
     mainbuffer_->createRingBuffer(MainBuffer::DEFAULT_ID);
@@ -310,64 +316,63 @@ void MainBufferTest::testRingBufferNonDefaultID()
     CPPUNIT_ASSERT(test_ring_buffer->putLength() == 0);
     CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 0);
 
-    test_ring_buffer->put(&testint1, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
+    test_ring_buffer->put(testbuf1);
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
     CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 0);
 
-    test_ring_buffer->put(&testint2, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 2*sizeof(int));
+    test_ring_buffer->put(testbuf2);
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 4);
     CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(MainBuffer::DEFAULT_ID) == 0);
 
-    int testget;
+    AudioBuffer testget(1);
+    AudioBuffer testgetlarge(100);
 
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id) == 2*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_id) == 2*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->get(&testget, sizeof(int), test_id) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_id) == sizeof(int));
-    CPPUNIT_ASSERT(testget == testint1);
-    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id) == 4);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_id) == 4);
+    CPPUNIT_ASSERT(test_ring_buffer->get(testget, test_id) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id) == 3);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_id) == 3);
+    CPPUNIT_ASSERT((*testget.getChannel(0))[0] == testsample1);
+    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == 1);
 
-    CPPUNIT_ASSERT(test_ring_buffer->get(&testget, 100, test_id) == sizeof(int));
-    CPPUNIT_ASSERT(testget == testint2);
+    CPPUNIT_ASSERT(test_ring_buffer->get(testgetlarge, test_id) == 3);
+    CPPUNIT_ASSERT((*testgetlarge.getChannel(0))[1] == testsample2[2]);
     CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id) == 0);
     CPPUNIT_ASSERT(test_ring_buffer->getLength(test_id) == 0);
-    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == 2*sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == 4);
 
 
     // test flush data
     CPPUNIT_ASSERT(test_ring_buffer->putLength() == 0);
-    test_ring_buffer->put(&testint1, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_id) == sizeof(int));
-
+    test_ring_buffer->put(testbuf1);
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_id) == 1);
 
     test_ring_buffer->flush(test_id);
     CPPUNIT_ASSERT(test_ring_buffer->putLength() == 0);
     CPPUNIT_ASSERT(test_ring_buffer->getLength(test_id) == 0);
     CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id) == 0);
-    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == 3*sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == 5);
 
     // test flush data
     CPPUNIT_ASSERT(test_ring_buffer->putLength() == 0);
-    test_ring_buffer->put(&testint1, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_id) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == 3*sizeof(int));
+    test_ring_buffer->put(testbuf1);
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_id) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == 5);
 
-    test_ring_buffer->discard(sizeof(int), test_id);
+    test_ring_buffer->discard(1, test_id);
     CPPUNIT_ASSERT(test_ring_buffer->putLength() == 0);
     CPPUNIT_ASSERT(test_ring_buffer->getLength(test_id) == 0);
     CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id) == 0);
-    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == 4*sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == 6);
 
     test_ring_buffer->removeReadPointer(test_id);
-
 }
 
-
+/*
 void MainBufferTest::testRingBufferFloat()
 {
     TITLE();
@@ -399,7 +404,7 @@ void MainBufferTest::testRingBufferFloat()
     test_ring_buffer->flush(MainBuffer::DEFAULT_ID);
     CPPUNIT_ASSERT(test_ring_buffer->putLength() == 0);
 
-}
+}*/
 
 
 void MainBufferTest::testTwoPointer()
@@ -410,12 +415,14 @@ void MainBufferTest::testTwoPointer()
     input_buffer->createReadPointer(MainBuffer::DEFAULT_ID);
     RingBuffer* output_buffer = mainbuffer_->getRingBuffer(MainBuffer::DEFAULT_ID);
 
-    int test_input = 12;
-    int test_output = 0;
+    SFLAudioSample test_sample = 12;
+
+    AudioBuffer test_input(&test_sample, 1);
+    AudioBuffer test_output(1);
 
-    input_buffer->put(&test_input, sizeof(int));
-    CPPUNIT_ASSERT(output_buffer->get(&test_output, sizeof(float), MainBuffer::DEFAULT_ID) == sizeof(float));
-    CPPUNIT_ASSERT(test_input == test_output);
+    input_buffer->put(test_input);
+    CPPUNIT_ASSERT(output_buffer->get(test_output, MainBuffer::DEFAULT_ID) == 1);
+    CPPUNIT_ASSERT(test_sample == (*test_output.getChannel(0))[0]);
 
 }
 
@@ -826,34 +833,38 @@ void MainBufferTest::testGetPutDataByID()
 
     mainbuffer_->bindCallID(test_id, MainBuffer::DEFAULT_ID);
 
-    int test_input1 = 12;
-    int test_input2 = 13;
-    int test_output = 0;
+    SFLAudioSample test_sample1 = 12;
+    SFLAudioSample test_sample2 = 13;
+
+    AudioBuffer test_input1(&test_sample1, 1);
+    AudioBuffer test_input2(&test_sample2, 1);
+    AudioBuffer test_output(1);
+    AudioBuffer test_output_large(100);
 
     // put by MainBuffer::DEFAULT_ID get by test_id without preleminary put
     CPPUNIT_ASSERT(mainbuffer_->availableForGetByID(MainBuffer::DEFAULT_ID, test_id) == 0);
-    CPPUNIT_ASSERT(mainbuffer_->getDataByID(&test_output, sizeof(int), MainBuffer::DEFAULT_ID, test_id) == 0);
+    CPPUNIT_ASSERT(mainbuffer_->getDataByID(test_output, MainBuffer::DEFAULT_ID, test_id) == 0);
 
     // put by MainBuffer::DEFAULT_ID, get by test_id
-    mainbuffer_->putData(&test_input1, sizeof(int), MainBuffer::DEFAULT_ID);
-    CPPUNIT_ASSERT(mainbuffer_->availableForGetByID(MainBuffer::DEFAULT_ID, test_id) == sizeof(int));
+    mainbuffer_->putData(test_input1, MainBuffer::DEFAULT_ID);
+    CPPUNIT_ASSERT(mainbuffer_->availableForGetByID(MainBuffer::DEFAULT_ID, test_id) == 1);
 
     // get by MainBuffer::DEFAULT_ID without preliminary input
     CPPUNIT_ASSERT(mainbuffer_->availableForGetByID(test_id, MainBuffer::DEFAULT_ID) == 0);
-    CPPUNIT_ASSERT(mainbuffer_->getDataByID(&test_output, 100, test_id, MainBuffer::DEFAULT_ID) == 0);
+    CPPUNIT_ASSERT(mainbuffer_->getDataByID(test_output_large, test_id, MainBuffer::DEFAULT_ID) == 0);
 
-    // pu by test_id get by test_id
-    mainbuffer_->putData(&test_input2, sizeof(int), test_id);
-    CPPUNIT_ASSERT(mainbuffer_->availableForGetByID(test_id, MainBuffer::DEFAULT_ID) == sizeof(int));
-    CPPUNIT_ASSERT(mainbuffer_->getDataByID(&test_output, 100, test_id, MainBuffer::DEFAULT_ID) == sizeof(int));
+    // put by test_id get by test_id
+    mainbuffer_->putData(test_input2, test_id);
+    CPPUNIT_ASSERT(mainbuffer_->availableForGetByID(test_id, MainBuffer::DEFAULT_ID) == 1);
+    CPPUNIT_ASSERT(mainbuffer_->getDataByID(test_output_large, test_id, MainBuffer::DEFAULT_ID) == 1);
     CPPUNIT_ASSERT(mainbuffer_->availableForGetByID(test_id, MainBuffer::DEFAULT_ID) == 0);
-    CPPUNIT_ASSERT(test_input2 == test_output);
+    CPPUNIT_ASSERT((*test_output_large.getChannel(0))[0] == test_sample2);
 
     // put/get by false id
-    mainbuffer_->putData(&test_input2, sizeof(int), false_id);
-    CPPUNIT_ASSERT(mainbuffer_->getDataByID(&test_input2, 100, false_id, false_id) == 0);
-    CPPUNIT_ASSERT(mainbuffer_->getDataByID(&test_input2, 100, MainBuffer::DEFAULT_ID, false_id) == 0);
-    CPPUNIT_ASSERT(mainbuffer_->getDataByID(&test_input2, 100, false_id, MainBuffer::DEFAULT_ID) == 0);
+    mainbuffer_->putData(test_input2, false_id);
+    CPPUNIT_ASSERT(mainbuffer_->getDataByID(test_output_large, false_id, false_id) == 0);
+    CPPUNIT_ASSERT(mainbuffer_->getDataByID(test_output_large, MainBuffer::DEFAULT_ID, false_id) == 0);
+    CPPUNIT_ASSERT(mainbuffer_->getDataByID(test_output_large, false_id, MainBuffer::DEFAULT_ID) == 0);
 
     mainbuffer_->unBindCallID(test_id, MainBuffer::DEFAULT_ID);
 }
@@ -867,31 +878,34 @@ void MainBufferTest::testGetPutData()
 
     mainbuffer_->bindCallID(test_id, MainBuffer::DEFAULT_ID);
 
-    int test_input1 = 12;
-    int test_input2 = 13;
-    int test_output;
+    SFLAudioSample test_sample1 = 12;
+    SFLAudioSample test_sample2 = 13;
+
+    AudioBuffer test_input1(&test_sample1, 1);
+    AudioBuffer test_input2(&test_sample2, 1);
+    AudioBuffer test_output(100);
 
     // get by test_id without preleminary put
     CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id) == 0);
-    CPPUNIT_ASSERT(mainbuffer_->getData(&test_output, 100, test_id) == 0);
+    CPPUNIT_ASSERT(mainbuffer_->getData(test_output, test_id) == 0);
 
     // put by MainBuffer::DEFAULT_ID, get by test_id
-    mainbuffer_->putData(&test_input1, sizeof(int), MainBuffer::DEFAULT_ID);
-    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id) == sizeof(int));
-    CPPUNIT_ASSERT(mainbuffer_->getData(&test_output, 100, test_id) == sizeof(int));
+    mainbuffer_->putData(test_input1, MainBuffer::DEFAULT_ID);
+    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id) == 1);
+    CPPUNIT_ASSERT(mainbuffer_->getData(test_output, test_id) == 1);
     CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id) == 0);
-    CPPUNIT_ASSERT(test_input1 == test_output);
+    CPPUNIT_ASSERT(test_sample1 == (*test_output.getChannel(0))[0]);
 
     // get by MainBuffer::DEFAULT_ID without preleminary put
     CPPUNIT_ASSERT(mainbuffer_->availableForGet(MainBuffer::DEFAULT_ID) == 0);
-    CPPUNIT_ASSERT(mainbuffer_->getData(&test_output, sizeof(int), MainBuffer::DEFAULT_ID) == 0);
+    CPPUNIT_ASSERT(mainbuffer_->getData(test_output, MainBuffer::DEFAULT_ID) == 0);
 
     // put by test_id, get by MainBuffer::DEFAULT_ID
-    mainbuffer_->putData(&test_input2, sizeof(int), test_id);
-    CPPUNIT_ASSERT(mainbuffer_->availableForGet(MainBuffer::DEFAULT_ID) == sizeof(int));
-    CPPUNIT_ASSERT(mainbuffer_->getData(&test_output, 100, MainBuffer::DEFAULT_ID) == sizeof(int));
+    mainbuffer_->putData(test_input2, test_id);
+    CPPUNIT_ASSERT(mainbuffer_->availableForGet(MainBuffer::DEFAULT_ID) == 1);
+    CPPUNIT_ASSERT(mainbuffer_->getData(test_output, MainBuffer::DEFAULT_ID) == 1);
     CPPUNIT_ASSERT(mainbuffer_->availableForGet(MainBuffer::DEFAULT_ID) == 0);
-    CPPUNIT_ASSERT(test_input2 == test_output);
+    CPPUNIT_ASSERT(test_sample2 == (*test_output.getChannel(0))[0]);
 
     mainbuffer_->unBindCallID(test_id, MainBuffer::DEFAULT_ID);
 
@@ -905,29 +919,28 @@ void MainBufferTest::testDiscardFlush()
     // mainbuffer_->createRingBuffer(test_id);
     mainbuffer_->bindCallID(test_id, MainBuffer::DEFAULT_ID);
 
-    int test_input1 = 12;
-    // int test_output_size;
-    // int init_size;
+    SFLAudioSample test_sample1 = 12;
+    AudioBuffer test_input1(&test_sample1, 1);
 
-    mainbuffer_->putData(&test_input1, sizeof(int), test_id);
-    CPPUNIT_ASSERT(mainbuffer_->availableForGet(MainBuffer::DEFAULT_ID) == sizeof(int));
-    mainbuffer_->discard(sizeof(int), MainBuffer::DEFAULT_ID);
+    mainbuffer_->putData(test_input1, test_id);
+    CPPUNIT_ASSERT(mainbuffer_->availableForGet(MainBuffer::DEFAULT_ID) == 1);
+    mainbuffer_->discard(1, MainBuffer::DEFAULT_ID);
     CPPUNIT_ASSERT(mainbuffer_->availableForGet(MainBuffer::DEFAULT_ID) == 0);
 
     CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id) == 0);
-    mainbuffer_->discard(sizeof(int), test_id);
+    mainbuffer_->discard(1, test_id);
     CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id) == 0);
 
-    CPPUNIT_ASSERT(mainbuffer_->getRingBuffer(test_id)->getReadPointer(MainBuffer::DEFAULT_ID) == sizeof(int));
+    CPPUNIT_ASSERT(mainbuffer_->getRingBuffer(test_id)->getReadPointer(MainBuffer::DEFAULT_ID) == 1);
     CPPUNIT_ASSERT(mainbuffer_->getRingBuffer(test_id)->getReadPointer(test_id) == 0);
 
 
     CPPUNIT_ASSERT(mainbuffer_->getRingBuffer(MainBuffer::DEFAULT_ID)->getReadPointer(test_id) == 0);
-    mainbuffer_->putData(&test_input1, 100, MainBuffer::DEFAULT_ID);
+    mainbuffer_->putData(test_input1, MainBuffer::DEFAULT_ID);
     CPPUNIT_ASSERT(mainbuffer_->getRingBuffer(MainBuffer::DEFAULT_ID)->getReadPointer(test_id) == 0);
 
-    mainbuffer_->discard(sizeof(int), test_id);
-    CPPUNIT_ASSERT(mainbuffer_->getRingBuffer(MainBuffer::DEFAULT_ID)->getReadPointer(test_id) == sizeof(int));
+    mainbuffer_->discard(1, test_id);
+    CPPUNIT_ASSERT(mainbuffer_->getRingBuffer(MainBuffer::DEFAULT_ID)->getReadPointer(test_id) == 1);
 
     mainbuffer_->unBindCallID(test_id, MainBuffer::DEFAULT_ID);
 }
@@ -973,66 +986,70 @@ void MainBufferTest::testRingBufferSeveralPointers()
     test_ring_buffer->createReadPointer(test_pointer1);
     test_ring_buffer->createReadPointer(test_pointer2);
 
-    int testint1 = 12;
-    int testint2 = 13;
-    int testint3 = 14;
-    int testint4 = 15;
-
-    int testoutput;
-
-    test_ring_buffer->put(&testint1, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer1) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer2) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == sizeof(int));
-
-    test_ring_buffer->put(&testint2, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 2*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer1) == 2*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer2) == 2*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == 2*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == 2*sizeof(int));
-
-    test_ring_buffer->put(&testint3, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 3*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer1) == 3*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer2) == 3*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == 3*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == 3*sizeof(int));
-
-    test_ring_buffer->put(&testint4, sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 4*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer1) == 4*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer2) == 4*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == 4*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == 4*sizeof(int));
-
-
-    CPPUNIT_ASSERT(test_ring_buffer->get(&testoutput, sizeof(int), test_pointer1) == sizeof(int));
-    CPPUNIT_ASSERT(testoutput == testint1);
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == 3*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == 4*sizeof(int));
-
-    CPPUNIT_ASSERT(test_ring_buffer->get(&testoutput, sizeof(int), test_pointer2) == sizeof(int));
-    CPPUNIT_ASSERT(testoutput == testint1);
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == 3*sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == 3*sizeof(int));
+    SFLAudioSample testint1 = 12;
+    SFLAudioSample testint2 = 13;
+    SFLAudioSample testint3 = 14;
+    SFLAudioSample testint4 = 15;
+    AudioBuffer test_input1(&testint1, 1);
+    AudioBuffer test_input2(&testint2, 1);
+    AudioBuffer test_input3(&testint3, 1);
+    AudioBuffer test_input4(&testint4, 1);
+
+    AudioBuffer test_output(1);
+
+    test_ring_buffer->put(test_input1);
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer1) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer2) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == 1);
+
+    test_ring_buffer->put(test_input2);
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 2);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer1) == 2);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer2) == 2);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == 2);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == 2);
+
+    test_ring_buffer->put(test_input3);
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 3);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer1) == 3);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer2) == 3);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == 3);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == 3);
+
+    test_ring_buffer->put(test_input4);
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 4);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer1) == 4);
+    CPPUNIT_ASSERT(test_ring_buffer->getLength(test_pointer2) == 4);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == 4);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == 4);
+
+
+    CPPUNIT_ASSERT(test_ring_buffer->get(test_output, test_pointer1) == 1);
+    CPPUNIT_ASSERT((*test_output.getChannel(0))[0] == testint1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == 3);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == 4);
+
+    CPPUNIT_ASSERT(test_ring_buffer->get(test_output, test_pointer2) == 1);
+    CPPUNIT_ASSERT((*test_output.getChannel(0))[0] == testint1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer1) == 3);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_pointer2) == 3);
 
     // However, we should no be alowed to read in our own ring buffer
-    // if we are either an AudioLayer or and RTP session
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 4*sizeof(int));
+    // if we are either an AudioLayer or an RTP session
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 4);
 
     // However, we should no be alowed to read in our own ring buffer
-    // if we are either an AudioLayer or and RTP session
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 4*sizeof(int));
+    // if we are either an AudioLayer or an RTP session
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 4);
 
     // However, we should no be alowed to read in our own ring buffer
-    // if we are either an AudioLayer or and RTP session
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 4*sizeof(int));
+    // if we are either an AudioLayer or an RTP session
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 4);
 
-    CPPUNIT_ASSERT(test_ring_buffer->discard(sizeof(int), test_pointer1) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->discard(sizeof(int), test_pointer2) == sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->discard(1, test_pointer1) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->discard(1, test_pointer2) == 1);
 
     test_ring_buffer->removeReadPointer(test_pointer1);
     test_ring_buffer->removeReadPointer(test_pointer2);
@@ -1190,17 +1207,18 @@ void MainBufferTest::testConference()
 
 
     // test putData default
-    int testint = 12;
+    SFLAudioSample testint = 12;
+    AudioBuffer testbuf(&testint, 1);
 
     CPPUNIT_ASSERT(mainbuffer_->availableForGet(MainBuffer::DEFAULT_ID) == 0);
     CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id1) == 0);
     CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id2) == 0);
     // put data test ring buffers
-    mainbuffer_->putData(&testint, sizeof(int), MainBuffer::DEFAULT_ID);
+    mainbuffer_->putData(testbuf, MainBuffer::DEFAULT_ID);
     test_ring_buffer = mainbuffer_->getRingBuffer(MainBuffer::DEFAULT_ID);
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id1) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id2) == sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id1) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id2) == 1);
     test_ring_buffer = mainbuffer_->getRingBuffer(test_id1);
     CPPUNIT_ASSERT(test_ring_buffer->putLength() == 0);
     CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 0);
@@ -1211,50 +1229,50 @@ void MainBufferTest::testConference()
     CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id1) == 0);
     // test mainbuffer availforget (get data even if some participant missing)
     CPPUNIT_ASSERT(mainbuffer_->availableForGet(MainBuffer::DEFAULT_ID) == 0);
-    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id1) == sizeof(int));
-    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id2) == sizeof(int));
+    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id1) == 1);
+    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id2) == 1);
     //putdata test ring buffers
-    mainbuffer_->putData(&testint, 100, test_id1);
+    mainbuffer_->putData(testbuf, test_id1);
     test_ring_buffer = mainbuffer_->getRingBuffer(MainBuffer::DEFAULT_ID);
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id1) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id2) == sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id1) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id2) == 1);
     test_ring_buffer = mainbuffer_->getRingBuffer(test_id1);
     test_ring_buffer = mainbuffer_->getRingBuffer(test_id2);
     CPPUNIT_ASSERT(test_ring_buffer->putLength() == 0);
     CPPUNIT_ASSERT(test_ring_buffer->availableForGet(MainBuffer::DEFAULT_ID) == 0);
     CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id1) == 0);
 
-    mainbuffer_->putData(&testint, 100, test_id2);
+    mainbuffer_->putData(testbuf, test_id2);
     test_ring_buffer = mainbuffer_->getRingBuffer(MainBuffer::DEFAULT_ID);
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id1) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id2) == sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id1) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id2) == 1);
     test_ring_buffer = mainbuffer_->getRingBuffer(test_id1);
     test_ring_buffer = mainbuffer_->getRingBuffer(test_id2);
     // test mainbuffer availforget
-    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id1) == sizeof(int));
-    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id2) == sizeof(int));
+    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id1) == 1);
+    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id2) == 1);
 
     // test getData default id (audio layer)
     test_ring_buffer = mainbuffer_->getRingBuffer(MainBuffer::DEFAULT_ID);
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id1) == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id2) == sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id1) == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id2) == 1);
     test_ring_buffer = mainbuffer_->getRingBuffer(test_id1);
     test_ring_buffer = mainbuffer_->getRingBuffer(test_id2);
     // test mainbuffer availforget
-    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id1) == sizeof(int));
-    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id2) == sizeof(int));
+    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id1) == 1);
+    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id2) == 1);
     // test getData test_id1 (audio layer)
     test_ring_buffer = mainbuffer_->getRingBuffer(MainBuffer::DEFAULT_ID);
-    CPPUNIT_ASSERT(test_ring_buffer->putLength() == sizeof(int));
-    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id2) == sizeof(int));
+    CPPUNIT_ASSERT(test_ring_buffer->putLength() == 1);
+    CPPUNIT_ASSERT(test_ring_buffer->availableForGet(test_id2) == 1);
     test_ring_buffer = mainbuffer_->getRingBuffer(test_id1);
     test_ring_buffer = mainbuffer_->getRingBuffer(test_id2);
 
     // test mainbuffer availforget
-    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id2) == sizeof(int));
+    CPPUNIT_ASSERT(mainbuffer_->availableForGet(test_id2) == 1);
     // test getData test_id2 (audio layer)
     test_ring_buffer = mainbuffer_->getRingBuffer(MainBuffer::DEFAULT_ID);
     test_ring_buffer = mainbuffer_->getRingBuffer(test_id1);
diff --git a/daemon/test/mainbuffertest.h b/daemon/test/mainbuffertest.h
index 9b63fa7f08e6a206d936de6d92de8f713ee6ddb3..58b946ce6049d0d6e04a4bb2912ab531201eb80e 100644
--- a/daemon/test/mainbuffertest.h
+++ b/daemon/test/mainbuffertest.h
@@ -37,7 +37,7 @@
 #include <cppunit/TestCase.h>
 #include <cppunit/TestSuite.h>
 
-#include <tr1/memory>
+#include <memory>
 
 class MainBuffer;
 /*
@@ -56,7 +56,7 @@ class MainBufferTest : public CppUnit::TestCase {
         CPPUNIT_TEST(testCallIDSet);
         CPPUNIT_TEST(testRingBufferInt);
         CPPUNIT_TEST(testRingBufferNonDefaultID);
-        CPPUNIT_TEST(testRingBufferFloat);
+        //CPPUNIT_TEST(testRingBufferFloat);
         CPPUNIT_TEST(testTwoPointer);
         CPPUNIT_TEST(testBindUnbindBuffer);
         CPPUNIT_TEST(testGetPutDataByID);
@@ -103,7 +103,7 @@ class MainBufferTest : public CppUnit::TestCase {
 
     private:
 
-        std::tr1::shared_ptr<MainBuffer> mainbuffer_;
+        std::unique_ptr<MainBuffer> mainbuffer_;
 };
 
 /* Register our test module */
diff --git a/daemon/test/resamplertest.cpp b/daemon/test/resamplertest.cpp
index 793335ee13350fd08f15492bcdaa2b799e525f88..2ba4fbb0ba80040395992dc2ef681440af12afb1 100644
--- a/daemon/test/resamplertest.cpp
+++ b/daemon/test/resamplertest.cpp
@@ -36,7 +36,7 @@
 #include "resamplertest.h"
 
 ResamplerTest::ResamplerTest() :
-    CppUnit::TestCase("Resampler module test"), inputBuffer(), outputBuffer()
+    CppUnit::TestCase("Resampler module test"), inputBuffer(MAX_BUFFER_LENGTH), outputBuffer(MAX_BUFFER_LENGTH)
 {}
 
 void ResamplerTest::setUp()
@@ -54,7 +54,7 @@ namespace {
     void print_buffer(T &buffer)
     {
         std::copy(buffer.begin(), buffer.end(),
-                std::ostream_iterator<SFLDataFormat>(std::cout, ", "));
+                std::ostream_iterator<SFLAudioSample>(std::cout, ", "));
         std::cout << std::endl;
     }
 }
@@ -69,16 +69,16 @@ void ResamplerTest::testUpsamplingRamp()
 
     performUpsampling(converter);
 
-    LowSmplrBuffer tmpInputBuffer;
-    HighSmplrBuffer tmpOutputBuffer;
+    AudioBuffer tmpInputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, 1, 8000);
+    AudioBuffer tmpOutputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, 1, 16000);
 
-    std::copy(inputBuffer.begin(), inputBuffer.begin() + tmpInputBuffer.size(), tmpInputBuffer.begin());
+    tmpInputBuffer.copy(inputBuffer);
     std::cout << "Input Buffer" << std::endl;
-    print_buffer(tmpInputBuffer);
+    print_buffer(*tmpInputBuffer.getChannel(0));
 
-    std::copy(outputBuffer.begin(), outputBuffer.begin() + tmpOutputBuffer.size(), tmpOutputBuffer.begin());
+    tmpOutputBuffer.copy(outputBuffer);
     std::cout << "Output Buffer" << std::endl;
-    print_buffer(tmpOutputBuffer);
+    print_buffer(*tmpOutputBuffer.getChannel(0));
 }
 
 void ResamplerTest::testDownsamplingRamp()
@@ -90,16 +90,16 @@ void ResamplerTest::testDownsamplingRamp()
 
     performDownsampling(converter);
 
-    HighSmplrBuffer tmpInputBuffer;
-    LowSmplrBuffer tmpOutputBuffer;
+    AudioBuffer tmpInputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, 1, 16000);
+    AudioBuffer tmpOutputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, 1, 8000);
 
-    std::copy(inputBuffer.begin(), inputBuffer.begin() + tmpInputBuffer.size(), tmpInputBuffer.begin());
+    tmpInputBuffer.copy(inputBuffer);
     std::cout << "Input Buffer" << std::endl;
-    print_buffer(tmpInputBuffer);
+    print_buffer(*tmpInputBuffer.getChannel(0));
 
-    std::copy(outputBuffer.begin(), outputBuffer.begin() + tmpOutputBuffer.size(), tmpOutputBuffer.begin());
+    tmpOutputBuffer.copy(outputBuffer);
     std::cout << "Output Buffer" << std::endl;
-    print_buffer(tmpOutputBuffer);
+    print_buffer(*tmpOutputBuffer.getChannel(0));
 }
 
 void ResamplerTest::testUpsamplingTriangle()
@@ -111,16 +111,16 @@ void ResamplerTest::testUpsamplingTriangle()
 
     performUpsampling(converter);
 
-    LowSmplrBuffer tmpInputBuffer;
-    HighSmplrBuffer tmpOutputBuffer;
+    AudioBuffer tmpInputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, 1, 8000);
+    AudioBuffer tmpOutputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, 1, 16000);
 
-    std::copy(inputBuffer.begin(), inputBuffer.begin() + tmpInputBuffer.size(), tmpInputBuffer.begin());
+    tmpInputBuffer.copy(inputBuffer);
     std::cout << "Input Buffer" << std::endl;
-    print_buffer(tmpInputBuffer);
+    print_buffer(*tmpInputBuffer.getChannel(0));
 
-    std::copy(outputBuffer.begin(), outputBuffer.begin() + tmpOutputBuffer.size(), tmpOutputBuffer.begin());
+    tmpOutputBuffer.copy(outputBuffer);
     std::cout << "Output Buffer" << std::endl;
-    print_buffer(tmpOutputBuffer);
+    print_buffer(*tmpOutputBuffer.getChannel(0));
 }
 
 void ResamplerTest::testDownsamplingTriangle()
@@ -132,16 +132,16 @@ void ResamplerTest::testDownsamplingTriangle()
 
     performDownsampling(converter);
 
-    HighSmplrBuffer tmpInputBuffer;
-    LowSmplrBuffer tmpOutputBuffer;
+    AudioBuffer tmpInputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, 1, 16000);
+    AudioBuffer tmpOutputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, 1, 8000);
 
-    std::copy(inputBuffer.begin(), inputBuffer.begin() + tmpInputBuffer.size(), tmpInputBuffer.begin());
+    tmpInputBuffer.copy(inputBuffer);
     std::cout << "Input Buffer" << std::endl;
-    print_buffer(tmpInputBuffer);
+    print_buffer(*tmpInputBuffer.getChannel(0));
 
-    std::copy(outputBuffer.begin(), outputBuffer.begin() + tmpOutputBuffer.size(), tmpOutputBuffer.begin());
+    tmpOutputBuffer.copy(outputBuffer);
     std::cout << "Output Buffer" << std::endl;
-    print_buffer(tmpOutputBuffer);
+    print_buffer(*tmpOutputBuffer.getChannel(0));
 }
 void ResamplerTest::testUpsamplingSine()
 {
@@ -153,16 +153,16 @@ void ResamplerTest::testUpsamplingSine()
 
     performUpsampling(converter);
 
-    LowSmplrBuffer tmpInputBuffer;
-    HighSmplrBuffer tmpOutputBuffer;
+    AudioBuffer tmpInputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, 1, 8000);
+    AudioBuffer tmpOutputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, 1, 16000);
 
-    std::copy(inputBuffer.begin(), inputBuffer.begin() + tmpInputBuffer.size(), tmpInputBuffer.begin());
+    tmpInputBuffer.copy(inputBuffer);
     std::cout << "Input Buffer" << std::endl;
-    print_buffer(tmpInputBuffer);
+    print_buffer(*tmpInputBuffer.getChannel(0));
 
-    std::copy(outputBuffer.begin(), outputBuffer.begin() + tmpOutputBuffer.size(), tmpOutputBuffer.begin());
+    tmpOutputBuffer.copy(outputBuffer);
     std::cout << "Output Buffer" << std::endl;
-    print_buffer(tmpOutputBuffer);
+    print_buffer(*tmpOutputBuffer.getChannel(0));
 }
 
 void ResamplerTest::testDownsamplingSine()
@@ -175,56 +175,59 @@ void ResamplerTest::testDownsamplingSine()
 
     performDownsampling(converter);
 
-    HighSmplrBuffer tmpInputBuffer;
-    LowSmplrBuffer tmpOutputBuffer;
+    AudioBuffer tmpInputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, 1, 16000);
+    AudioBuffer tmpOutputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, 1, 8000);
 
-    std::copy(inputBuffer.begin(), inputBuffer.begin() + tmpInputBuffer.size(), tmpInputBuffer.begin());
+    tmpInputBuffer.copy(inputBuffer);
     std::cout << "Input Buffer" << std::endl;
-    print_buffer(tmpInputBuffer);
+    print_buffer(*tmpInputBuffer.getChannel(0));
 
-    std::copy(outputBuffer.begin(), outputBuffer.begin() + tmpOutputBuffer.size(), tmpOutputBuffer.begin());
+    tmpOutputBuffer.copy(outputBuffer);
     std::cout << "Output Buffer" << std::endl;
-    print_buffer(tmpOutputBuffer);
+    print_buffer(*tmpOutputBuffer.getChannel(0));
 }
 
 void ResamplerTest::generateRamp()
 {
-    for (size_t i = 0; i < inputBuffer.size(); ++i)
-        inputBuffer[i] = i;
+    std::vector<SFLAudioSample>* buf = inputBuffer.getChannel(0);
+    for (size_t i = 0; i < buf->size(); ++i)
+        (*buf)[i] = i;
 }
 
 void ResamplerTest::generateTriangularSignal()
 {
-    for (size_t i = 0; i < inputBuffer.size(); ++i)
-        inputBuffer[i] = i * 10;
+    std::vector<SFLAudioSample>* buf = inputBuffer.getChannel(0);
+    for (size_t i = 0; i < buf->size(); ++i)
+        (*buf)[i] = i * 10;
 }
 
 void ResamplerTest::generateSineSignal()
 {
-    for (size_t i = 0; i < inputBuffer.size(); ++i)
-        inputBuffer[i] = (SFLDataFormat) (1000.0 * sin(i));
+    std::vector<SFLAudioSample>* buf = inputBuffer.getChannel(0);
+    for (size_t i = 0; i < buf->size(); ++i)
+        (*buf)[i] = (SFLAudioSample) (1000.0 * sin(i));
 }
 
 void ResamplerTest::performUpsampling(SamplerateConverter &converter)
 {
-    LowSmplrBuffer tmpInputBuffer;
-    HighSmplrBuffer tmpOutputBuffer;
+    AudioBuffer tmpInputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, 1, 8000);
+    AudioBuffer tmpOutputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, 1, 16000);
 
-    for (size_t i = 0, j = 0; i < (inputBuffer.size() / 2); i += tmpInputBuffer.size(), j += tmpOutputBuffer.size()) {
-        std::copy(inputBuffer.begin() + i, inputBuffer.begin() + tmpInputBuffer.size() + i, tmpInputBuffer.begin());
-        converter.resample(tmpInputBuffer.data(), tmpOutputBuffer.data(), tmpOutputBuffer.size(), 8000, 16000, tmpInputBuffer.size());
-        std::copy(tmpOutputBuffer.begin(), tmpOutputBuffer.end(), outputBuffer.begin() + j);
+    for (size_t i = 0, j = 0; i < (inputBuffer.samples() / 2); i += tmpInputBuffer.samples(), j += tmpOutputBuffer.samples()) {
+        tmpInputBuffer.copy(inputBuffer, i);
+        converter.resample(tmpInputBuffer, tmpOutputBuffer);
+        outputBuffer.copy(tmpOutputBuffer, -1, 0, j);
     }
 }
 
 void ResamplerTest::performDownsampling(SamplerateConverter &converter)
 {
-    HighSmplrBuffer tmpInputBuffer;
-    LowSmplrBuffer tmpOutputBuffer;
+    AudioBuffer tmpInputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, 1, 16000);
+    AudioBuffer tmpOutputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, 1, 8000);
 
-    for (size_t i = 0, j = 0; i < inputBuffer.size(); i += tmpInputBuffer.size(), j += tmpOutputBuffer.size()) {
-        std::copy(inputBuffer.begin() + i, inputBuffer.begin() + tmpInputBuffer.size() + i, tmpInputBuffer.begin());
-        converter.resample(tmpInputBuffer.data(), tmpOutputBuffer.data(), tmpOutputBuffer.size(), 16000, 8000, tmpInputBuffer.size());
-        std::copy(tmpOutputBuffer.begin(), tmpOutputBuffer.end(), outputBuffer.begin() + j);
+    for (size_t i = 0, j = 0; i < inputBuffer.samples(); i += tmpInputBuffer.samples(), j += tmpOutputBuffer.samples()) {
+        tmpInputBuffer.copy(inputBuffer, i);
+        converter.resample(tmpInputBuffer, tmpOutputBuffer);
+        outputBuffer.copy(tmpOutputBuffer, -1, 0, j);
     }
 }
diff --git a/daemon/test/resamplertest.h b/daemon/test/resamplertest.h
index ecd8b205bf3e8a81d57ab6927893da5ede303d99..a5fffc53b71dbebed83efe692aea48b843c6f690 100644
--- a/daemon/test/resamplertest.h
+++ b/daemon/test/resamplertest.h
@@ -45,8 +45,8 @@
 #define TMP_LOWSMPLR_BUFFER_LENGTH 160
 #define TMP_HIGHSMPLR_BUFFER_LENGTH 320
 
-typedef std::tr1::array<SFLDataFormat, TMP_LOWSMPLR_BUFFER_LENGTH> LowSmplrBuffer;
-typedef std::tr1::array<SFLDataFormat, TMP_HIGHSMPLR_BUFFER_LENGTH> HighSmplrBuffer;
+//typedef std::tr1::array<SFLDataFormat, TMP_LOWSMPLR_BUFFER_LENGTH> LowSmplrBuffer;
+//typedef std::tr1::array<SFLDataFormat, TMP_HIGHSMPLR_BUFFER_LENGTH> HighSmplrBuffer;
 
 class ResamplerTest : public CppUnit::TestCase {
 
@@ -138,12 +138,14 @@ private:
     /**
      * Used to store input samples
      */
-    std::tr1::array<SFLDataFormat, MAX_BUFFER_LENGTH> inputBuffer;
+    //std::tr1::array<SFLDataFormat, MAX_BUFFER_LENGTH> inputBuffer;
+    AudioBuffer inputBuffer;
 
     /**
      * Used to receive output samples
      */
-    std::tr1::array<SFLDataFormat, MAX_BUFFER_LENGTH> outputBuffer;
+    //std::tr1::array<SFLDataFormat, MAX_BUFFER_LENGTH> outputBuffer;
+    AudioBuffer outputBuffer;
 };
 
 /* Register the test module */
diff --git a/daemon/test/sflphoned-sample.yml b/daemon/test/sflphoned-sample.yml
index 7a268593312bd4d0af3994fbd93f1f27ecb917f8..faf60f63639091dc688426bdcc4f3d6d29ce4d7d 100644
--- a/daemon/test/sflphoned-sample.yml
+++ b/daemon/test/sflphoned-sample.yml
@@ -2,17 +2,19 @@
 accounts:
 - alias: SFL test
   audioCodecs: 0/3/8/9/110/111/112/
+  autoAnswer: false
   credential:
   - Account.password: 1234
-    Account.realm:
+    Account.realm: 
     Account.username: sfltest
-  displayName:
+  displayName: 
   dtmfType: overrtp
   enable: false
   hostname: localhost
   id: Account:1334389473
   interface: default
-  mailbox:
+  keepAlive: false
+  mailbox: 
   port: 5060
   publishAddr: 0.0.0.0
   publishPort: 5060
@@ -20,55 +22,75 @@ accounts:
   ringtoneEnabled: true
   ringtonePath: /usr/share/sflphone/ringtones/konga.ul
   sameasLocal: true
-  serviceRoute:
+  serviceRoute: 
   srtp:
     enable: false
-    keyExchange:
+    keyExchange: 
     rtpFallback: false
   stunEnabled: false
   stunServer: stun.sflphone.org
   tls:
-    calist:
-    certificate:
-    ciphers:
+    calist: 
+    certificate: 
+    ciphers: 
     enable: false
     method: TLSv1
-    password:
-    privateKey:
+    password: 
+    privateKey: 
     requireCertif: true
-    server:
+    server: 
     timeout: 2
     tlsPort: 5061
     verifyClient: true
     verifyServer: true
   type: SIP
+  useragent: SFLphone-test
   username: sfltest
   videoCodecs:
+  - bitrate: 400
+    enabled: true
+    name: H263-2000
+    parameters: 
+  - bitrate: 400
+    enabled: true
+    name: H264
+    parameters: profile-level-id=428014
+  - bitrate: 400
+    enabled: true
+    name: MP4V-ES
+    parameters: 
+  - bitrate: 400
+    enabled: true
+    name: VP8
+    parameters: 
   zrtp:
     displaySas: true
     displaySasOnce: false
     helloHashEnabled: true
     notSuppWarning: true
 - alias: IP2IP
-  codecs: 0/
+  audioCodecs: 0/3/8/9/110/111/112/
+  autoAnswer: false
   credential:
-  - password:
-    realm: '*'
-    username:
-  displayName:
+  - Account.password: 
+    Account.realm: 
+    Account.username: 
+  displayName: 
   dtmfType: true
   enable: true
-  hostname:
+  hostname: 
   id: IP2IP
   interface: default
-  mailbox:
+  keepAlive: false
+  mailbox: 
   port: 5060
-  publishAddr:
+  publishAddr: 
   publishPort: 5060
+  registrationexpire: 60
   ringtoneEnabled: true
   ringtonePath: /usr/share/sflphone/ringtones/konga.ul
   sameasLocal: true
-  serviceRoute:
+  serviceRoute: 
   srtp:
     enable: false
     keyExchange: sdes
@@ -76,28 +98,39 @@ accounts:
   stunEnabled: false
   stunServer: stun.sflphone.org
   tls:
-    calist:
-    certificate:
-    ciphers:
+    calist: 
+    certificate: 
+    ciphers: 
     enable: false
     method: TLSv1
-    password:
-    privateKey:
+    password: 
+    privateKey: 
     requireCertif: true
-    server:
+    server: 
     timeout: 2
     tlsPort: 5061
     verifyClient: true
     verifyServer: true
   type: SIP
-  username:
+  useragent: SFLphone-test
+  username: 
   videoCodecs:
   - bitrate: 400
     enabled: true
     name: H263-2000
+    parameters: 
   - bitrate: 400
     enabled: true
     name: H264
+    parameters: profile-level-id=428014
+  - bitrate: 400
+    enabled: true
+    name: MP4V-ES
+    parameters: 
+  - bitrate: 400
+    enabled: true
+    name: VP8
+    parameters: 
   zrtp:
     displaySas: true
     displaySasOnce: false
@@ -107,9 +140,9 @@ preferences:
   historyLimit: 30
   historyMaxCalls: 20
   md5Hash: false
-  notifyMails: false
-  order: Account:1328115463/Account:1328115393/Account:1328115062/Account:1316122317/Account:1316122284/Account:1316121900/Account:1316121889/Account:1316121691/Account:1316121662/Account:1316121661/Account:1316121654/Account:1316121611/Account:1316121607/Account:1316121605/Account:1316121602/Account:1312584532/Account:1312398082/Account:1312398066/Account:1309188361/Account:1309187807/Account:1309187723/Account:1309187670/Account:1309187609/Account:1309187081/Account:1308839853/Account:1308839662/Account:1308839447/Account:1308839359/Account:1308839335/Account:1308838875/Account:1308838713/Account:1308838236/Account:1307975440/Account:1307975347/Account:1307974800/Account:1307974672/Account:1307974527/Account:1303487773/Account:1303247743/Account:1302895321/Account:1302892836/Account:1302891834/Account:1302882519/Account:1302207377/Account:1302207262/Account:1302204136/Account:1302204108/Account:1294850905/Account:1294850775/Account:1294850618/Account:1294849651/Account:1294849602/Account:1294849310/Account:1288964768/Account:1288964603/Account:1288964434/Account:1288964141/Account:1288964134/
+  order: Account:1375906657/Account:1328115463/Account:1328115393/Account:1328115062/Account:1316122317/Account:1316122284/Account:1316121900/Account:1316121889/Account:1316121691/Account:1316121662/Account:1316121661/Account:1316121654/Account:1316121611/Account:1316121607/Account:1316121605/Account:1316121602/Account:1312584532/Account:1312398082/Account:1312398066/Account:1309188361/Account:1309187807/Account:1309187723/Account:1309187670/Account:1309187609/Account:1309187081/Account:1308839853/Account:1308839662/Account:1308839447/Account:1308839359/Account:1308839335/Account:1308838875/Account:1308838713/Account:1308838236/Account:1307975440/Account:1307975347/Account:1307974800/Account:1307974672/Account:1307974527/Account:1303487773/Account:1303247743/Account:1302895321/Account:1302892836/Account:1302891834/Account:1302882519/Account:1302207377/Account:1302207262/Account:1302204136/Account:1302204108/Account:1294850905/Account:1294850775/Account:1294850618/Account:1294849651/Account:1294849602/Account:1294849310/Account:1288964768/Account:1288964603/Account:1288964434/Account:1288964141/Account:1288964134/
   portNum: 5060
+  registrationexpire: 180
   searchBarDisplay: true
   zeroConfenable: false
   zoneToneChoice: North America
@@ -121,7 +154,7 @@ voipPreferences:
   zidFile: true
 hooks:
   iax2Enabled: false
-  numberAddPrefix:
+  numberAddPrefix: 
   numberEnabled: false
   sipEnabled: false
   urlCommand: x-www-browser
@@ -136,25 +169,23 @@ audio:
   alwaysRecording: false
   audioApi: pulseaudio
   echoCancel: false
-  echoDelayLength: 0
-  echoTailLength: 100
   noiseReduce: true
   pulse:
     devicePlayback: alsa_output.pci-0000_00_1b.0.analog-stereo
     deviceRecord: alsa_input.pci-0000_00_1b.0.analog-stereo
     deviceRingtone: alsa_output.pci-0000_00_1b.0.analog-stereo
-  recordPath:
+  recordPath: /home/tristan
   volumeMic: 100
   volumeSpkr: 100
 video:
-  v4l2Channel:
-  v4l2Dev:
-  v4l2Rate:
-  v4l2Size:
+  v4l2Channel: 
+  v4l2Dev: 
+  v4l2Rate: 
+  v4l2Size: 
 shortcuts:
-  hangUp:
-  pickUp:
-  popupWindow:
-  toggleHold:
-  togglePickupHangup:
+  hangUp: 
+  pickUp: 
+  popupWindow: 
+  toggleHold: 
+  togglePickupHangup: 
 ...
diff --git a/daemon/test/sflphonedrc-sample b/daemon/test/sflphonedrc-sample
deleted file mode 100644
index 6d0064a7c50fc350fb1d55aa1faef4002c321427..0000000000000000000000000000000000000000
--- a/daemon/test/sflphonedrc-sample
+++ /dev/null
@@ -1,74 +0,0 @@
-[Account:1239059899]
-Account.alias=1260@sip.sflphone.org
-Account.enable=1
-Account.type=SIP
-hostname=sflphone.org
-password=NIPAgmLo
-username=1260
-
-[Account:1243544046]
-Account.alias=Manu
-Account.enable=1
-Account.mailbox=*97
-Account.type=SIP
-hostname=192.168.50.3
-password=sfl-137pw
-username=137
-
-[Addressbook]
-Addressbook.contact_photo=0
-Addressbook.enable=1
-Addressbook.list=1243608768.30329.0@emilou-desktop/1243456917.15690.23@emilou-desktop/
-Addressbook.max_results=25
-Addressbook.phone_business=1
-Addressbook.phone_home=0
-Addressbook.phone_mobile=0
-
-[Audio]
-Alsa.cardID_In=0
-Alsa.cardID_Out=0
-Alsa.framesize=20
-Alsa.plugin=default
-Alsa.sampleRate=44100
-Record.path=/home/emilou
-Rings.ringChoice=/usr/share/sflphone/ringtones/konga.ul
-Volume.micro=100
-Volume.speakers=100
-
-[Hooks]
-Hooks.iax2_enabled=0
-Hooks.phone_number_add_prefix=
-Hooks.phone_number_enabled=0
-Hooks.sip_enabled=0
-Hooks.url_command=x-www-browser
-Hooks.url_sip_field=X-sflphone-url
-
-[Preferences]
-Accounts.order=Account:1243544046/Account:1239138829/
-Audio.api=1
-Dialpad.display=0
-History.enabled=1
-History.limit=30
-History.maxCalls=20
-Notify.all=1
-Notify.mails=0
-Options.zoneToneChoice=North America
-Pulseaudio.volumeCtrl=1
-Registration.expire=180
-Ringtones.enable=1
-SIP.portNum=5060
-Searchbar.display=1
-Start.hidden=0
-Volume.display=0
-Window.popup=0
-Zeroconf.enable=0
-
-[VoIPLink]
-DTMF.playDtmf=1
-DTMF.playTones=1
-DTMF.pulseLength=250
-DTMF.sendDTMFas=0
-STUN.enable=0
-STUN.server=stun.sflphone.org
-VoIPLink.symmetric=1
-
diff --git a/daemon/test/siptest.cpp b/daemon/test/siptest.cpp
index b00ab8bae06fcccd83ae912fd5f29dbc956e8055..8c27304c4e8f4e3da17857ae1846fe2bb2314d69 100644
--- a/daemon/test/siptest.cpp
+++ b/daemon/test/siptest.cpp
@@ -28,8 +28,9 @@
  *  as that of the covered work.
  */
 
-#include <stdlib.h>
-#include <stdio.h>
+#include <unistd.h>
+#include <cstdlib>
+#include <cstdio>
 #include <iostream>
 #include <fstream>
 
diff --git a/gnome/.cproject b/gnome/.cproject
deleted file mode 100644
index 108d69e9da01af604c24174c2e40c1c0f4c0cc48..0000000000000000000000000000000000000000
--- a/gnome/.cproject
+++ /dev/null
@@ -1,628 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?fileVersion 4.0.0?>
-
-<cproject>
-	<storageModule moduleId="org.eclipse.cdt.core.settings">
-		<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.666814495">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.666814495" moduleId="org.eclipse.cdt.core.settings" name="Release">
-				<externalSettings/>
-				<extensions>
-					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="sflphone-gtk" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.666814495" name="Release" parent="org.eclipse.cdt.build.core.emptycfg">
-					<folderInfo id="cdt.managedbuild.toolchain.gnu.base.666814495.1839755914" name="/" resourcePath="">
-						<toolChain id="cdt.managedbuild.toolchain.gnu.base.1195789621" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
-							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1493285969" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
-							<builder id="cdt.managedbuild.target.gnu.builder.base.421214348" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="-1" superClass="cdt.managedbuild.target.gnu.builder.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.archiver.base.1558364998" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.731757910" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1299938473" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
-								<option id="gnu.c.compiler.option.include.paths.1303328171" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
-									<listOptionValue builtIn="false" value="/usr/include/gtk-2.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/glib-2.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/dbus-1.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/libgnome-2.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/libgnomeui-2.0"/>
-									<listOptionValue builtIn="false" value="/usr/include"/>
-								</option>
-								<option id="gnu.c.compiler.option.preprocessor.def.symbols.1676995808" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="&quot;ICONS_DIR=&quot;/usr/share/sflphone\&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;CODECS_DIR=&quot;/usr/lib/sflphone/codecs\&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;DATA_DIR=&quot;/usr/share/sflphone\&quot;"/>
-								</option>
-								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1938301835" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.linker.base.981882139" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base">
-								<option id="gnu.c.link.option.paths.137448498" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
-									<listOptionValue builtIn="false" value="/usr/include/gtk-2.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/glib-2.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/dbus-1.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/libgnome-2.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/libgnomeui-2.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/libgnome-2.0/libgnome"/>
-								</option>
-								<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1274984809" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-								</inputType>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.963771621" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.assembler.base.1924201184" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
-								<option id="gnu.both.asm.option.include.paths.1513412733" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths"/>
-								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.938125330" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-							</tool>
-						</toolChain>
-					</folderInfo>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
-			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
-			<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-			<storageModule moduleId="scannerConfiguration">
-				<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
-				<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="makefileGenerator">
-						<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1995189473;cdt.managedbuild.config.gnu.exe.debug.1995189473.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.44474984;cdt.managedbuild.tool.gnu.c.compiler.input.1565605211">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.666814495;cdt.managedbuild.toolchain.gnu.base.666814495.1839755914;cdt.managedbuild.tool.gnu.c.compiler.base.1299938473;cdt.managedbuild.tool.gnu.c.compiler.input.1938301835">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-			</storageModule>
-		</cconfiguration>
-		<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1995189473">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1995189473" moduleId="org.eclipse.cdt.core.settings" name="Debug">
-				<externalSettings/>
-				<extensions>
-					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
-			<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="gnome" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1995189473" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
-					<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1995189473." name="/" resourcePath="">
-						<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1423428378" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
-							<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.285066138" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
-							<builder id="cdt.managedbuild.target.gnu.builder.exe.debug.100968868" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="-1" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
-							<tool id="cdt.managedbuild.tool.gnu.archiver.base.417731669" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.187669799" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
-								<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1648950260" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
-								<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1642920658" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.44474984" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
-								<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.228151721" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
-								<option id="gnu.c.compiler.exe.debug.option.debugging.level.676359726" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
-								<option id="gnu.c.compiler.option.include.paths.1167204962" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
-									<listOptionValue builtIn="false" value="/usr/include"/>
-									<listOptionValue builtIn="false" value="/usr/include/glib-2.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/gtk-2.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/dbus-1.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/libgnome-2.0"/>
-									<listOptionValue builtIn="false" value="/usr/include/libgnomeui-2.0"/>
-								</option>
-								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1565605211" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1289604635" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
-								<option id="gnu.c.link.option.paths.1262921055" name="Library search path (-L)" superClass="gnu.c.link.option.paths"/>
-								<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.861769146" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-								</inputType>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.172868928" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"/>
-							<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.210816158" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
-								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1667826927" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-							</tool>
-						</toolChain>
-					</folderInfo>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-			<storageModule moduleId="scannerConfiguration">
-				<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
-				<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="makefileGenerator">
-						<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-					<buildOutputProvider>
-						<openAction enabled="true" filePath=""/>
-						<parser enabled="true"/>
-					</buildOutputProvider>
-					<scannerInfoProvider id="specsFile">
-						<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-						<parser enabled="true"/>
-					</scannerInfoProvider>
-				</profile>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1995189473;cdt.managedbuild.config.gnu.exe.debug.1995189473.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.44474984;cdt.managedbuild.tool.gnu.c.compiler.input.1565605211">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-				<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.666814495;cdt.managedbuild.toolchain.gnu.base.666814495.1839755914;cdt.managedbuild.tool.gnu.c.compiler.base.1299938473;cdt.managedbuild.tool.gnu.c.compiler.input.1938301835">
-					<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="makefileGenerator">
-							<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-					<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
-						<buildOutputProvider>
-							<openAction enabled="true" filePath=""/>
-							<parser enabled="true"/>
-						</buildOutputProvider>
-						<scannerInfoProvider id="specsFile">
-							<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
-							<parser enabled="true"/>
-						</scannerInfoProvider>
-					</profile>
-				</scannerConfigBuildInfo>
-			</storageModule>
-		</cconfiguration>
-	</storageModule>
-	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-		<project id="sflphone-gtk.null.1710073778" name="sflphone-gtk"/>
-	</storageModule>
-</cproject>
diff --git a/gnome/.project b/gnome/.project
deleted file mode 100644
index 0ca91571783f5c16eb2a2490ddacbc4cc482ac1e..0000000000000000000000000000000000000000
--- a/gnome/.project
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>gnome</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-			<triggers>clean,full,incremental,</triggers>
-			<arguments>
-				<dictionary>
-					<key>?name?</key>
-					<value></value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.append_environment</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
-					<value>all</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildArguments</key>
-					<value>-j</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildCommand</key>
-					<value>make</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
-					<value>clean</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.contents</key>
-					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
-					<value>false</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
-					<value>all</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.stopOnError</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
-					<value>true</value>
-				</dictionary>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
-		<nature>org.eclipse.cdt.core.cnature</nature>
-	</natures>
-</projectDescription>
diff --git a/gnome/src/actions.c b/gnome/src/actions.c
index 35cd55a39c4f3fa2c262bd8917296a485226f880..a2df2ba573cccfb9917f7b7221e2518ceb632157 100644
--- a/gnome/src/actions.c
+++ b/gnome/src/actions.c
@@ -130,12 +130,17 @@ status_bar_display_account()
     account_t *acc = account_list_get_current();
     status_tray_icon_online(acc != NULL);
 
+    static const char * const account_types[] = {
+        N_("(SIP)"),
+        N_("(IAX)")
+    };
+
     gchar* msg;
     if (acc) {
-        msg = g_markup_printf_escaped("%s %s (%s)" ,
-                                      _("Using account"),
+        const guint type_idx = account_is_IAX(acc);
+        msg = g_markup_printf_escaped(_("Using account %s %s"),
                                       (gchar*) account_lookup(acc, CONFIG_ACCOUNT_ALIAS),
-                                      (gchar*) account_lookup(acc, CONFIG_ACCOUNT_TYPE));
+                                      _(account_types[type_idx]));
     } else {
         msg = g_markup_printf_escaped(_("No registered accounts"));
     }
diff --git a/gnome/src/codeclist.c b/gnome/src/codeclist.c
index 9baf922c37c35d61db85684aa66f4fddd00252f7..ac4319a4c8d84fb91f3c196c2501983982182ff4 100644
--- a/gnome/src/codeclist.c
+++ b/gnome/src/codeclist.c
@@ -58,6 +58,7 @@ static codec_t *codec_create(gint payload, gchar **specs)
         codec->bitrate = g_strdup(specs[2]);
         codec->sample_rate = atoi(specs[1]);
     }
+    codec->channels = specs[3]?atoi(specs[3]):1;
     codec->is_active = TRUE;
 
     g_strfreev(specs);
@@ -131,6 +132,7 @@ codec_t *codec_create_new_from_caps(codec_t *original)
         codec->name = g_strdup(original->name);
         codec->sample_rate = original->sample_rate;
         codec->bitrate = g_strdup(original->bitrate);
+        codec->channels = original->channels;
     }
 
     return codec;
diff --git a/gnome/src/codeclist.h b/gnome/src/codeclist.h
index 8a11335d05f5653c846a5e3ed75c595524f69b0d..c73addbd2f419f54a0584f55b7dddcc6b8a61950 100644
--- a/gnome/src/codeclist.h
+++ b/gnome/src/codeclist.h
@@ -47,6 +47,8 @@ typedef struct {
     gint sample_rate;
     /** Bitrate */
     gchar * bitrate;
+    /** Channel number */
+    gint channels;
 } codec_t;
 
 /** @struct codec_t
diff --git a/gnome/src/config/accountconfigdialog.c b/gnome/src/config/accountconfigdialog.c
index aa171bcb3a57fdb178f28bdd4ec6a1c7f9aa5c6d..c38e7a34bfe642150b48b0d6697f0a4f7668b838 100644
--- a/gnome/src/config/accountconfigdialog.c
+++ b/gnome/src/config/accountconfigdialog.c
@@ -56,6 +56,7 @@
 #include "tlsadvanceddialog.h"
 #include "dbus/dbus.h"
 #include "utils.h"
+#include "seekslider.h"
 
 /**
  * TODO: tidy this up
@@ -95,6 +96,7 @@ static GtkWidget *file_chooser;
 static GtkWidget *security_tab;
 static GtkWidget *advanced_tab;
 static GtkWidget *overrtp;
+static GtkWidget *ringtone_seekslider;
 
 typedef struct OptionsData {
     account_t *account;
@@ -171,7 +173,6 @@ select_dtmf_type(void)
 
 static GPtrArray* get_new_credential(void)
 {
-    gint row_count = 0;
     GPtrArray *credential_array = g_ptr_array_new();
 
     GtkTreeIter iter;
@@ -188,8 +189,6 @@ static GPtrArray* get_new_credential(void)
                            COLUMN_CREDENTIAL_PASSWORD, &password,
                            -1);
 
-        g_debug("Row %d: %s %s %s", row_count++, username, password, realm);
-
         GHashTable * new_table = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                        g_free, g_free);
         g_hash_table_insert(new_table, g_strdup(CONFIG_ACCOUNT_REALM), realm);
@@ -1063,6 +1062,18 @@ static void ringtone_enabled_cb(G_GNUC_UNUSED GtkWidget *widget, gpointer data,
     gtk_widget_set_sensitive(data, !gtk_widget_is_sensitive(data));
 }
 
+void update_ringtone_slider(guint position, guint size)
+{
+    if (ringtone_seekslider)
+        sfl_seekslider_update_scale(SFL_SEEKSLIDER(ringtone_seekslider), position, size);
+}
+
+static void ringtone_changed_cb(GtkWidget *widget, gpointer data)
+{
+    GtkFileChooser *chooser = GTK_FILE_CHOOSER(widget);
+    SFLSeekSlider *seekslider = data;
+    g_object_set(seekslider, "file-path", gtk_file_chooser_get_filename(chooser), NULL);
+}
 
 static GtkWidget*
 create_audiocodecs_configuration(const account_t *account)
@@ -1112,24 +1123,36 @@ create_audiocodecs_configuration(const account_t *account)
     enable_tone = gtk_check_button_new_with_mnemonic(_("_Enable ringtones"));
     const gboolean ringtone_enabled = g_strcmp0(ptr, "true") == 0;
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enable_tone), ringtone_enabled);
-    g_signal_connect(G_OBJECT(enable_tone) , "clicked", G_CALLBACK(ringtone_enabled_cb), file_chooser);
+    g_signal_connect(G_OBJECT(enable_tone), "clicked", G_CALLBACK(ringtone_enabled_cb), file_chooser);
     gtk_grid_attach(GTK_GRID(grid), enable_tone, 0, 0, 1, 1);
 
     // file chooser button
-    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_chooser) , g_get_home_dir());
+    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_chooser), g_get_home_dir());
     ptr = account_lookup(account, CONFIG_RINGTONE_PATH);
-    gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_chooser) , ptr);
+    gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_chooser), ptr);
     gtk_widget_set_sensitive(file_chooser, ringtone_enabled);
 
+    // button to preview ringtones
+    ringtone_seekslider = GTK_WIDGET(sfl_seekslider_new());
+    g_object_set(G_OBJECT(ringtone_seekslider), "file-path", ptr, NULL);
+    g_signal_connect(G_OBJECT(file_chooser), "selection-changed", G_CALLBACK(ringtone_changed_cb), ringtone_seekslider);
+
     GtkFileFilter *filter = gtk_file_filter_new();
     gtk_file_filter_set_name(filter, _("Audio Files"));
     gtk_file_filter_add_pattern(filter, "*.wav");
     gtk_file_filter_add_pattern(filter, "*.ul");
     gtk_file_filter_add_pattern(filter, "*.au");
+    gtk_file_filter_add_pattern(filter, "*.flac");
+    gtk_file_filter_add_pattern(filter, "*.ogg");
 
     gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), filter);
     gtk_grid_attach(GTK_GRID(grid), file_chooser, 0, 1, 1, 1);
 
+    GtkWidget *alignment =  gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
+    gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 6, 6);
+    gtk_container_add(GTK_CONTAINER(alignment), ringtone_seekslider);
+    gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);
+
     gtk_widget_show_all(vbox);
 
     return vbox;
@@ -1150,7 +1173,7 @@ create_videocodecs_configuration(const account_t *a)
     gtk_box_pack_start(GTK_BOX (vbox), videocodecs, FALSE, FALSE, 0);
     gtk_widget_set_size_request(GTK_WIDGET (videocodecs), -1, 200);
     gtk_widget_show(videocodecs);
-    gtk_container_add(GTK_CONTAINER (videocodecs) , box);
+    gtk_container_add(GTK_CONTAINER (videocodecs), box);
 
     gtk_widget_show_all(vbox);
 
@@ -1208,9 +1231,6 @@ static void update_account_from_basic_tab(account_t *account)
             account_replace(account, CONFIG_ACCOUNT_ROUTESET,
                             gtk_entry_get_text(GTK_ENTRY(entry_route_set)));
 
-            account_replace(account, CONFIG_ACCOUNT_USERAGENT,
-                            gtk_entry_get_text(GTK_ENTRY(entry_user_agent)));
-
             gboolean v = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_stun_check_box));
             account_replace(account, CONFIG_STUN_ENABLE,
                             bool_to_string(v));
@@ -1279,6 +1299,8 @@ static void update_account_from_basic_tab(account_t *account)
                         gtk_entry_get_text(GTK_ENTRY(local_port_spin_box)));
     }
 
+    account_replace(account, CONFIG_ACCOUNT_USERAGENT,
+                    gtk_entry_get_text(GTK_ENTRY(entry_user_agent)));
     account_replace(account, CONFIG_ACCOUNT_ALIAS, gtk_entry_get_text(GTK_ENTRY(entry_alias)));
     account_replace(account, CONFIG_ACCOUNT_TYPE, proto);
     account_replace(account, CONFIG_ACCOUNT_HOSTNAME, gtk_entry_get_text(GTK_ENTRY(entry_hostname)));
diff --git a/gnome/src/config/accountconfigdialog.h b/gnome/src/config/accountconfigdialog.h
index 79dbced498896369be13e007b5b432e09cac48c8..ff7ec1cacfedf0854c98cd1fe9c4d977b5a7b462 100644
--- a/gnome/src/config/accountconfigdialog.h
+++ b/gnome/src/config/accountconfigdialog.h
@@ -53,4 +53,10 @@ show_account_window(account_t *a, SFLPhoneClient *client, gboolean is_new);
  */
 void update_account_from_dialog(GtkWidget *dialog, account_t *a);
 
+/*
+ * @param position The position of the slider
+ * @param size The size of the slider
+ */
+void update_ringtone_slider(guint position, guint size);
+
 #endif
diff --git a/gnome/src/config/audioconf.c b/gnome/src/config/audioconf.c
index 98f49d4187d36fb34f08a89f6dbe7a6ecfea9ffb..0793bb32d27fe4aca02345ab9ab2d4c2e8cf524b 100644
--- a/gnome/src/config/audioconf.c
+++ b/gnome/src/config/audioconf.c
@@ -57,6 +57,7 @@ enum {
     COLUMN_CODEC_NAME,
     COLUMN_CODEC_FREQUENCY,
     COLUMN_CODEC_BITRATE,
+    COLUMN_CODEC_CHANNELS,
     CODEC_COLUMN_COUNT
 };
 
@@ -91,12 +92,14 @@ fill_codec_list(const account_t *account)
             gtk_list_store_append(codecStore, &iter);
             gchar *samplerate = g_strdup_printf("%d " KHZ, (gint) (c->sample_rate * 0.001));
             gchar *bitrate = g_strdup_printf("%s " KBPS, c->bitrate);
+            gchar *channels = g_strdup_printf("%d", c->channels);
 
             gtk_list_store_set(codecStore, &iter,
                                COLUMN_CODEC_ACTIVE, c->is_active,
                                COLUMN_CODEC_NAME, c->name,
                                COLUMN_CODEC_FREQUENCY, samplerate,
                                COLUMN_CODEC_BITRATE, bitrate,
+                               COLUMN_CODEC_CHANNELS, channels,
                                -1);
             g_free(samplerate);
             g_free(bitrate);
@@ -511,6 +514,7 @@ audiocodecs_box(const account_t *account)
             G_TYPE_STRING, /* Name */
             G_TYPE_STRING, /* Frequency */
             G_TYPE_STRING, /* Bitrate */
+            G_TYPE_STRING, /* Channels */
             G_TYPE_STRING  /* Bandwidth */);
 
     // Create codec tree view with list store
@@ -548,6 +552,11 @@ audiocodecs_box(const account_t *account)
     treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Bitrate"), renderer, "text", COLUMN_CODEC_BITRATE, NULL);
     gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
 
+    // Channels column
+    renderer = gtk_cell_renderer_text_new();
+    treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Channels"), renderer, "text", COLUMN_CODEC_CHANNELS, NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
+
     gtk_container_add(GTK_CONTAINER(scrolledWindow), codecTreeView);
 
     // Create button box
diff --git a/gnome/src/config/tlsadvanceddialog.c b/gnome/src/config/tlsadvanceddialog.c
index d7f4148cb65f33ba27c35a244ad2e6dacee21e39..0a41f43d17cf2e057fa3cbc6783dc12cb0cc7cac 100644
--- a/gnome/src/config/tlsadvanceddialog.c
+++ b/gnome/src/config/tlsadvanceddialog.c
@@ -189,34 +189,27 @@ void show_advanced_tls_options(account_t *account, SFLPhoneClient *client)
     gtk_grid_attach(GTK_GRID(grid), privateKeyPasswordEntry, 1, 6, 1, 1);
 
     /* TLS protocol methods */
-    GtkTreeIter iter;
 
-    GtkListStore * tlsProtocolMethodListStore =  gtk_list_store_new(1, G_TYPE_STRING);
     label = gtk_label_new_with_mnemonic(_("TLS protocol method"));
     gtk_grid_attach(GTK_GRID(grid), label, 0, 7, 1, 1);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 
+    GtkWidget *tlsProtocolMethodCombo = gtk_combo_box_text_new();
     gchar** supported_tls_method = dbus_get_supported_tls_method();
 
-    GtkTreeIter supported_tls_method_iter;
+    gint supported_tls_method_idx = 0;
+    gint idx = 0;
     for (char **supported_tls_method_ptr = supported_tls_method; supported_tls_method_ptr && *supported_tls_method_ptr; supported_tls_method_ptr++) {
-        gtk_list_store_append(tlsProtocolMethodListStore, &iter);
-        gtk_list_store_set(tlsProtocolMethodListStore, &iter, 0, *supported_tls_method_ptr, -1);
-
+        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(tlsProtocolMethodCombo), NULL, *supported_tls_method_ptr);
+        /* make sure current TLS method from is active */
         if (g_strcmp0(*supported_tls_method_ptr, tls_method) == 0)
-            supported_tls_method_iter = iter;
+            supported_tls_method_idx = idx;
+        ++idx;
     }
+    gtk_combo_box_set_active(GTK_COMBO_BOX(tlsProtocolMethodCombo), supported_tls_method_idx);
 
-    GtkWidget *tlsProtocolMethodCombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(tlsProtocolMethodListStore));
     gtk_label_set_mnemonic_widget(GTK_LABEL(label), tlsProtocolMethodCombo);
     gtk_grid_attach(GTK_GRID(grid), tlsProtocolMethodCombo, 1, 7, 1, 1);
-    g_object_unref(G_OBJECT(tlsProtocolMethodListStore));
-
-    GtkCellRenderer *tlsProtocolMethodCellRenderer;
-    tlsProtocolMethodCellRenderer = gtk_cell_renderer_text_new();
-    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(tlsProtocolMethodCombo), tlsProtocolMethodCellRenderer, TRUE);
-    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(tlsProtocolMethodCombo), tlsProtocolMethodCellRenderer, "text", 0, NULL);
-    gtk_combo_box_set_active_iter(GTK_COMBO_BOX(tlsProtocolMethodCombo), &supported_tls_method_iter);
 
     /* Cipher list */
     GtkWidget * cipherListEntry;
diff --git a/gnome/src/contacts/calltree.c b/gnome/src/contacts/calltree.c
index 6de67257930656c3a8df6c72dce70e1dec644912..0adf6c0738312cd0d086fb102cb31b1962fa19aa 100644
--- a/gnome/src/contacts/calltree.c
+++ b/gnome/src/contacts/calltree.c
@@ -101,6 +101,12 @@ is_conference(GtkTreeModel *model, GtkTreeIter *iter)
     return result;
 }
 
+static void
+update_ringtone_seekslider_path(callable_obj_t *call)
+{
+    main_window_update_seekslider(call->_recordfile);
+}
+
 /* Call back when the user click on a call in the list */
 static void
 call_selected_cb(GtkTreeSelection *sel, SFLPhoneClient *client)
@@ -132,8 +138,11 @@ call_selected_cb(GtkTreeSelection *sel, SFLPhoneClient *client)
         callable_obj_t *selected_call = calllist_get_call(active_calltree_tab, id);
         g_free(id);
 
-        if (selected_call)
+        if (selected_call) {
             calltab_select_call(active_calltree_tab, selected_call);
+            if (calltab_has_name(active_calltree_tab, HISTORY))
+                update_ringtone_seekslider_path(selected_call);
+        }
     }
 
     update_actions(client);
diff --git a/gnome/src/dbus/callmanager-introspec.xml b/gnome/src/dbus/callmanager-introspec.xml
index c86062e82a331a9f052063557685d6cb4fe8b64e..400cae60615b60c2240b0c7ab629eb1f9647d398 100644
--- a/gnome/src/dbus/callmanager-introspec.xml
+++ b/gnome/src/dbus/callmanager-introspec.xml
@@ -211,6 +211,11 @@
             <arg type="as" name="participants" direction="in"/>
         </method>
 
+        <method name="isConferenceParticipant" tp:name-for-bindings="isConferenceParticipant">
+            <arg type="s" name="callID" direction="in"/>
+            <arg type="b" name="isParticipant" direction="out"/>
+        </method>
+
         <method name="addParticipant" tp:name-for-bindings="addParticipant">
             <tp:added version="0.9.7"/>
             <tp:docstring>
@@ -392,6 +397,7 @@
 
         <signal name="updatePlaybackScale" tp:name-for-bindings="updatePlaybackScale">
             <tp:docstring/>
+            <arg type="s" name="filepath" />
             <arg type="i" name="position" />
             <arg type="i" name="size" />
         </signal>
diff --git a/gnome/src/dbus/dbus.c b/gnome/src/dbus/dbus.c
index 58edccabe9b12d27d527cfbb3b735410c2cb8756..f9218508aa7aa835138c8c8dc970d1223d716655 100644
--- a/gnome/src/dbus/dbus.c
+++ b/gnome/src/dbus/dbus.c
@@ -50,6 +50,7 @@
 #include "assistant.h"
 #include "accountlist.h"
 #include "accountlistconfigdialog.h"
+#include "accountconfigdialog.h"
 #include "messaging/message_tab.h"
 
 #include "sflphone_client.h"
@@ -412,9 +413,11 @@ record_playback_stopped_cb(G_GNUC_UNUSED DBusGProxy *proxy, const gchar *filepat
 }
 
 static void
-update_playback_scale_cb(G_GNUC_UNUSED DBusGProxy *proxy, guint position, guint size)
+update_playback_scale_cb(G_GNUC_UNUSED DBusGProxy *proxy,
+        const gchar *file_path, guint position, guint size)
 {
-    main_window_update_playback_scale(position, size);
+    if (!main_window_update_playback_scale(file_path, position, size))
+        update_ringtone_slider(position, size);
 }
 
 static void
@@ -648,8 +651,6 @@ gboolean dbus_connect(GError **error, SFLPhoneClient *client)
     const char *configurationmanager_object_instance = "/org/sflphone/SFLphone/ConfigurationManager";
     const char *configurationmanager_interface = "org.sflphone.SFLphone.ConfigurationManager";
 
-    g_type_init();
-
     DBusGConnection *connection = dbus_g_bus_get(DBUS_BUS_SESSION, error);
     if (connection == NULL) {
         g_warning("could not establish connection with session bus");
@@ -810,7 +811,7 @@ gboolean dbus_connect(GError **error, SFLPhoneClient *client)
     dbus_g_proxy_connect_signal(call_proxy, "recordPlaybackStopped",
                                 G_CALLBACK(record_playback_stopped_cb), client, NULL);
 
-    dbus_g_proxy_add_signal(call_proxy, "updatePlaybackScale", G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
+    dbus_g_proxy_add_signal(call_proxy, "updatePlaybackScale", G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "updatePlaybackScale",
                                 G_CALLBACK(update_playback_scale_cb), NULL, NULL);
 
diff --git a/gnome/src/dbus/instance-introspec.xml b/gnome/src/dbus/instance-introspec.xml
index f564d54cc1ed7bb941af0b35fb063928cd2a9f88..f3d1373a6409b7875a4d80db5bf0f815f285d637 100644
--- a/gnome/src/dbus/instance-introspec.xml
+++ b/gnome/src/dbus/instance-introspec.xml
@@ -29,5 +29,8 @@
 				</tp:docstring>
 			</arg>
 		</method>
+        <signal name="started" tp:name-for-bindings="started">
+            <tp:docstring>Notify clients that daemon has started</tp:docstring>
+        </signal>
     </interface>
 </node>
diff --git a/gnome/src/mainwindow.c b/gnome/src/mainwindow.c
index 01acc808f8bd5d0b170037ceffbc22a507a03c2d..68d0a7555f86f5bff8a3ae962da82e55a15435a4 100644
--- a/gnome/src/mainwindow.c
+++ b/gnome/src/mainwindow.c
@@ -546,10 +546,14 @@ main_window_confirm_go_clear(callable_obj_t * c, SFLPhoneClient *client)
     add_error_dialog(GTK_WIDGET(mini_dialog));
 }
 
-void
-main_window_update_playback_scale(guint current, guint size)
+gboolean
+main_window_update_playback_scale(const gchar *file_path, guint current, guint size)
 {
-     sfl_seekslider_update_scale(SFL_SEEKSLIDER(seekslider), current, size);
+    if (sfl_seekslider_has_path(SFL_SEEKSLIDER(seekslider), file_path)) {
+        sfl_seekslider_update_scale(SFL_SEEKSLIDER(seekslider), current, size);
+        return TRUE;
+    }
+    return FALSE;
 }
 
 void
@@ -589,3 +593,9 @@ main_window_pause_keygrabber(gboolean value)
 {
     pause_grabber = value;
 }
+
+void
+main_window_update_seekslider(const gchar *recordfile)
+{
+    g_object_set(G_OBJECT(seekslider), "file-path", recordfile, NULL);
+}
diff --git a/gnome/src/mainwindow.h b/gnome/src/mainwindow.h
index 3e27fdbc10517d509a78e800815959eb61f69246..b183ca644da53fe135dbc4d92b340c298da0af19 100644
--- a/gnome/src/mainwindow.h
+++ b/gnome/src/mainwindow.h
@@ -107,7 +107,7 @@ void focus_on_searchbar_in();
  * if the size is 0 or if the current value is larger than the size, the cursor position
  * is moved at the end of the scale.
  */
-void main_window_update_playback_scale(guint current, guint size);
+gboolean main_window_update_playback_scale(const gchar *file_path, guint current, guint size);
 
 void main_window_set_playback_scale_sensitive();
 
@@ -131,4 +131,7 @@ void main_window_pause_keygrabber(gboolean value);
 void main_window_reset_playback_scale();
 
 void main_window_bring_to_front(SFLPhoneClient *client, guint32 timestamp);
+
+void main_window_update_seekslider(const gchar *recordfile);
+
 #endif
diff --git a/gnome/src/seekslider.c b/gnome/src/seekslider.c
index 2ebdc35f1a409bf4691139329ec066bca61ac9ed..23ebd4a00f947bb38254210ace9a6583250e88fb 100644
--- a/gnome/src/seekslider.c
+++ b/gnome/src/seekslider.c
@@ -36,7 +36,6 @@
 #include <string.h>
 #include "seekslider.h"
 #include "dbus.h"
-#include "calltab.h"
 
 /**
  * SECTION:sfl-seekslider
@@ -89,13 +88,18 @@ struct SFLSeekSliderPrivate
     gboolean is_dragging;
     gboolean can_update_scale;
     gboolean is_playing;
+    gchar *file_path;
 };
 
 enum
 {
     PROP_0,
+    PROP_FILE_PATH,
+    N_PROPERTIES
 };
 
+static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
+
 G_DEFINE_TYPE(SFLSeekSlider, sfl_seekslider, GTK_TYPE_HBOX)
 
 static void
@@ -108,6 +112,10 @@ sfl_seekslider_class_init(SFLSeekSliderClass *klass)
     object_class->set_property = sfl_seekslider_set_property;
     object_class->get_property = sfl_seekslider_get_property;
 
+    obj_properties[PROP_FILE_PATH] = g_param_spec_string("file-path", "File path",
+            "Set file path for playback", "" /* default value */, G_PARAM_READWRITE);
+
+    g_object_class_install_properties(object_class, N_PROPERTIES, obj_properties);
     g_type_class_add_private(klass, sizeof(SFLSeekSliderPrivate));
 }
 
@@ -186,6 +194,7 @@ sfl_seekslider_init(SFLSeekSlider *seekslider)
     seekslider->priv->current = 0;
     seekslider->priv->size = 0;
     seekslider->priv->is_playing = FALSE;
+    seekslider->priv->file_path = NULL;
 }
 
 static void
@@ -199,6 +208,9 @@ sfl_seekslider_finalize(GObject *object)
     seekslider = SFL_SEEKSLIDER(object);
     g_return_if_fail(seekslider->priv != NULL);
 
+    /* Ensure that we've stopped playback */
+    sfl_seekslider_stop_playback_record_cb(NULL, seekslider);
+
     G_OBJECT_CLASS(sfl_seekslider_parent_class)->finalize(object);
 }
 
@@ -206,15 +218,54 @@ sfl_seekslider_finalize(GObject *object)
 static void
 sfl_seekslider_set_property (GObject *object, guint prop_id, const GValue *value G_GNUC_UNUSED, GParamSpec *pspec)
 {
-    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    SFLSeekSlider *self = SFL_SEEKSLIDER(object);
+
+    switch (prop_id)
+    {
+        case PROP_FILE_PATH:
+            /* no change */
+            if (g_strcmp0(self->priv->file_path, g_value_get_string(value)) == 0)
+                break;
+
+            /* cache is_playing as it will be modified */
+            const gboolean resume_playing = self->priv->is_playing;
+            if (resume_playing)
+                sfl_seekslider_stop_playback_record_cb(NULL, self);
+
+            g_free(self->priv->file_path);
+            self->priv->file_path = g_value_dup_string(value);
+            g_debug("filepath: %s\n", self->priv->file_path);
+
+            if (resume_playing)
+                sfl_seekslider_play_playback_record_cb(NULL, self);
+            break;
+
+        default:
+            /* We don't have any other property... */
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
 }
 
 static void
 sfl_seekslider_get_property (GObject *object, guint prop_id, GValue *value G_GNUC_UNUSED, GParamSpec *pspec)
 {
-    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    SFLSeekSlider *self = SFL_SEEKSLIDER(object);
+
+    switch (prop_id)
+    {
+        case PROP_FILE_PATH:
+            g_value_set_string(value, self->priv->file_path);
+            break;
+
+        default:
+            /* We don't have any other property... */
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
 }
 
+
 /**
  * sfl_seekslider_new:
  * @shell_player: the #RBShellPlayer instance
@@ -298,37 +349,30 @@ on_playback_scale_scrolled_cb(GtkWidget *widget G_GNUC_UNUSED, GdkEvent *event G
 
 static void sfl_seekslider_play_playback_record_cb (GtkButton *button G_GNUC_UNUSED, gpointer user_data)
 {
-    SFLSeekSlider *seekslider = SFL_SEEKSLIDER(user_data);
+    SFLSeekSlider *self = SFL_SEEKSLIDER(user_data);
 
-    callable_obj_t *selectedCall = calltab_get_selected_call(history_tab);
-    if (selectedCall == NULL)
+    if (self->priv->file_path == NULL || (*self->priv->file_path == 0))
         return;
 
-    g_debug("Start selected call file playback %s", selectedCall->_recordfile);
-    seekslider->priv->is_playing = selectedCall->_record_is_playing =
-        dbus_start_recorded_file_playback(selectedCall->_recordfile);
+    g_debug("Start file playback %s", self->priv->file_path);
+    self->priv->is_playing = dbus_start_recorded_file_playback(self->priv->file_path);
 
-    if (seekslider->priv->is_playing)
-        sfl_seekslider_set_display(seekslider, SFL_SEEKSLIDER_DISPLAY_PAUSE);
+    if (self->priv->is_playing)
+        sfl_seekslider_set_display(self, SFL_SEEKSLIDER_DISPLAY_PAUSE);
 }
 
 static void sfl_seekslider_stop_playback_record_cb (GtkButton *button G_GNUC_UNUSED, gpointer user_data)
 {
-    SFLSeekSlider *seekslider = SFL_SEEKSLIDER(user_data);
+    SFLSeekSlider *self = SFL_SEEKSLIDER(user_data);
 
-    callable_obj_t *selectedCall = calltab_get_selected_call(history_tab);
-    if (selectedCall == NULL)
+    if (self->priv->file_path == NULL || (*self->priv->file_path == 0))
         return;
 
-    if (selectedCall->_recordfile == NULL ||
-        strlen(selectedCall->_recordfile) == 0)
-        return;
-
-    dbus_stop_recorded_file_playback(selectedCall->_recordfile);
-    g_debug("Stop selected call file playback %s", selectedCall->_recordfile);
-    seekslider->priv->is_playing = selectedCall->_record_is_playing = FALSE;
+    dbus_stop_recorded_file_playback(self->priv->file_path);
+    g_debug("Stop file playback %s", self->priv->file_path);
+    self->priv->is_playing = FALSE;
 
-    sfl_seekslider_set_display(seekslider, SFL_SEEKSLIDER_DISPLAY_PLAY);
+    sfl_seekslider_set_display(self, SFL_SEEKSLIDER_DISPLAY_PLAY);
 }
 
 void sfl_seekslider_update_timelabel(SFLSeekSlider *seekslider, guint current, guint size)
@@ -416,3 +460,9 @@ void sfl_seekslider_reset(SFLSeekSlider *seekslider)
     seekslider->priv->is_playing = FALSE;
     seekslider->priv->can_update_scale = TRUE;
 }
+
+gboolean
+sfl_seekslider_has_path(SFLSeekSlider *seekslider, const gchar *file_path)
+{
+    return g_strcmp0(seekslider->priv->file_path, file_path) == 0;
+}
diff --git a/gnome/src/seekslider.h b/gnome/src/seekslider.h
index 325084624305d467e6e814427bcc4611147be7bf..72082265622b7dc4ad399656751614fbfe845bd3 100644
--- a/gnome/src/seekslider.h
+++ b/gnome/src/seekslider.h
@@ -68,6 +68,8 @@ void sfl_seekslider_update_timelabel(SFLSeekSlider *seekslider, guint current, g
 
 void sfl_seekslider_set_display(SFLSeekSlider *seekslider, SFLSeekSliderDisplay display);
 
+gboolean sfl_seekslider_has_path(SFLSeekSlider *seekslider, const gchar *file_path);
+
 void sfl_seekslider_reset(SFLSeekSlider *seekslider);
 
 #endif /* __RB_SEEKSLIDER_H */
diff --git a/gnome/tests/check_dbus.c b/gnome/tests/check_dbus.c
index 8bd3e0af8b67e5ccab44e9101f2b592d7468d3d6..5214aebc80798a6e262aaf51d0291ce3887e40f0 100644
--- a/gnome/tests/check_dbus.c
+++ b/gnome/tests/check_dbus.c
@@ -36,7 +36,6 @@
 
 START_TEST(test_dbus_connect)
 {
-    g_type_init();
     GError *error = NULL;
     SFLPhoneClient *client = sflphone_client_new();
     fail_unless(dbus_connect(&error, client) == TRUE, "dbus_connect () returns FALSE");
diff --git a/hudson-sflphone-script.sh b/hudson-sflphone-script.sh
index c19624d73e9b8e87e66532d385deb9c4e9e957d5..2b5d0360ea8465a704e6b7c85891da193c943423 100755
--- a/hudson-sflphone-script.sh
+++ b/hudson-sflphone-script.sh
@@ -42,22 +42,22 @@ CONFIGDIR=~/.config
 SFLCONFDIR=${CONFIGDIR}/sflphone
 
 function run_code_analysis {
-	# Check if cppcheck is installed on the system
-	if [ `which cppcheck &>/dev/null ; echo $?` -ne 1 ] ; then
-		pushd src
-		cppcheck . --enable=all --xml --inline-suppr 2> cppcheck-report.xml
-		popd
-	fi
+    # Check if cppcheck is installed on the system
+    if [ `which cppcheck &>/dev/null ; echo $?` -ne 1 ] ; then
+        pushd src
+        cppcheck . --enable=all --xml --inline-suppr 2> cppcheck-report.xml
+        popd
+    fi
 }
 
 
 function gen_doxygen {
-	# Check if doxygen is installed on the system
-	if [ `which doxygen &>/dev/null ; echo $?` -ne 1 ] ; then
-		pushd doc/doxygen
-		doxygen core-doc.cfg.in
-		popd
-	fi
+    # Check if doxygen is installed on the system
+    if [ `which doxygen &>/dev/null ; echo $?` -ne 1 ] ; then
+        pushd doc/doxygen
+        doxygen core-doc.cfg.in
+        popd
+    fi
 }
 
 function launch_functional_test_daemon {
@@ -102,67 +102,64 @@ function launch_functional_test_daemon {
 
 
 function build_daemon {
-	# Compile the daemon
-	pushd daemon
-	# Run static analysis code tool
-	if [ $CODE_ANALYSIS == 1 ]; then
-		run_code_analysis
-	fi
-	make distclean
-	./autogen.sh
-	# Compile pjproject first
-	pushd libs/pjproject-2.1.0
-	./autogen.sh
-	CFLAGS=-fPIC ./configure
-	make && make dep
-	popd
-	./configure --prefix=/usr
-	make clean
-	# Compile src code
-	make -j
-	# Remove the previous XML test file
-	rm -rf $XML_RESULTS
-	# Compile unit tests
-	make check
-	popd
+    pushd daemon
+    # Run static analysis code tool
+    if [ $CODE_ANALYSIS == 1 ]; then
+        run_code_analysis
+    fi
+    make distclean
+
+    ./autogen.sh || exit 1
+    # Compile pjproject first
+    pushd libs
+    ./compile_pjsip.sh
+    popd
+
+    # Compile the daemon
+    ./configure --prefix=/usr
+    make clean
+    make -j
+    # Remove the previous XML test file
+    rm -rf $XML_RESULTS
+    # Compile unit tests
+    make check
+    popd
 }
 
 function build_gnome {
-	# Compile the daemon
-	pushd daemon
-  killall sflphoned
-	make distclean
-	./autogen.sh
-  # Compile pjproject first
-	pushd libs/pjproject-2.1.0
-	./autogen.sh
-	CFLAGS=-fPIC ./configure
-	make && make dep
-	popd
-	./configure --prefix=/usr
-	make clean
-	# Compile src code
-	make -j
-  ./src/sflphoned&
-	popd
-
-	# Compile the plugins
-	pushd plugins
-	make distclean
-	./autogen.sh
-	./configure --prefix=/usr
-	make -j
-	popd
-
-	# Compile the client
-	pushd gnome
-	make distclean
-	./autogen.sh
-	./configure --prefix=/usr
-	make clean
-	make -j 1
-	make check
-	popd
+    pushd daemon
+    killall sflphoned
+    make distclean
+
+    # Compile pjproject first
+    pushd libs
+    ./compile_pjsip.sh
+    popd
+
+    # Compile daemon
+    ./configure --prefix=/usr
+    make clean
+    make -j
+    ./src/sflphoned &
+    popd
+
+    # Compile the plugins
+    pushd plugins
+    make distclean
+    ./autogen.sh || exit 1
+    ./configure --prefix=/usr
+    make -j
+    popd
+
+    # Compile the client
+    pushd gnome
+    make distclean
+    ./autogen.sh || exit 1
+    ./configure --prefix=/usr
+    make clean
+    make -j 1
+    make check
+    popd
 }
 
 function build_kde {
@@ -177,41 +174,41 @@ function build_kde {
 
 
 if [ "$#" -eq 0 ]; then   # Script needs at least one command-line argument.
-	echo "Usage $0 -b select which one to build: daemon or gnome
-				  -t enable unit tests after build"
-	exit $E_OPTERR
+    echo "Usage $0 -b select which one to build: daemon or gnome
+                  -t enable unit tests after build"
+    exit $E_OPTERR
 fi
 
 
 git clean -f -d -x
 
 while getopts ":b: t a d" opt; do
-	case $opt in
-		b)
-			echo "-b was triggered. Parameter: $OPTARG" >&2
-			BUILD=$OPTARG
-			;;
-		t)
-			echo "-t was triggered. Tests will be run" >&2
-			TEST=1
-			;;
-		a)
-			echo "-a was triggered. Static code analysis will be run" >&2
-			CODE_ANALYSIS=1
-			;;
-		d)
-			echo "-d was triggered. Doxygen documentation will be generated" >&2
-			DOXYGEN=1
-			;;
-		\?)
-			echo "Invalid option: -$OPTARG" >&2
-			exit 1
-			;;
-		:)
-			echo "Option -$OPTARG requires an argument." >&2
-			exit 1
-			;;
-		esac
+    case $opt in
+        b)
+            echo "-b was triggered. Parameter: $OPTARG" >&2
+            BUILD=$OPTARG
+            ;;
+        t)
+            echo "-t was triggered. Tests will be run" >&2
+            TEST=1
+            ;;
+        a)
+            echo "-a was triggered. Static code analysis will be run" >&2
+            CODE_ANALYSIS=1
+            ;;
+        d)
+            echo "-d was triggered. Doxygen documentation will be generated" >&2
+            DOXYGEN=1
+            ;;
+        \?)
+            echo "Invalid option: -$OPTARG" >&2
+            exit 1
+            ;;
+        :)
+            echo "Option -$OPTARG requires an argument." >&2
+            exit 1
+            ;;
+        esac
 done
 
 # Call appropriate build function, with parameters if needed
diff --git a/tools/build-system/README.launchpad b/tools/build-system/README.launchpad
new file mode 100644
index 0000000000000000000000000000000000000000..eabd74ef2b5c7ab8723276614fa23f15a46038b7
--- /dev/null
+++ b/tools/build-system/README.launchpad
@@ -0,0 +1,9 @@
+To push packages for a new Ubuntu distribution on launchpad, you'll need to
+modify the following files:
+
+tools/build-system/launchpad/dput.conf
+tools/build-system/setenv.sh
+
+See commit 1b19e3869aa5e4632b8b043f47024297218ed2c5 for an example.
+
+In addition, you'll have to modify the sflphone-package-manager job on Jenkins
diff --git a/tools/build-system/launchpad/dput.conf b/tools/build-system/launchpad/dput.conf
index 01af29933e620b9fbefc03f25de7429bb084d6e1..12f1c2b688c0c8c11ba84f441caf4fbf912f5b41 100644
--- a/tools/build-system/launchpad/dput.conf
+++ b/tools/build-system/launchpad/dput.conf
@@ -33,6 +33,13 @@ incoming = ~savoirfairelinux/ubuntu/raring
 login = anonymous
 allow_unsigned_uploads = 0
 
+[sflphone-saucy]
+fqdn = ppa.launchpad.net
+method = ftp
+incoming = ~savoirfairelinux/ubuntu/saucy
+login = anonymous
+allow_unsigned_uploads = 0
+
 [sflphone-nightly-natty]
 fqdn = ppa.launchpad.net
 method = ftp
@@ -61,6 +68,13 @@ incoming = ~savoirfairelinux/sflphone-nightly/ubuntu/raring
 login = anonymous
 allow_unsigned_uploads = 0
 
+[sflphone-nightly-saucy]
+fqdn = ppa.launchpad.net
+method = ftp
+incoming = ~savoirfairelinux/sflphone-nightly/ubuntu/saucy
+login = anonymous
+allow_unsigned_uploads = 0
+
 [sflphone-testing-precise]
 fqdn = ppa.launchpad.net
 method = ftp
diff --git a/tools/build-system/launchpad/sflphone-common-video/debian/control b/tools/build-system/launchpad/sflphone-common-video/debian/control
index f8638f67a74dd80a981fbb187e77114e2f475d16..bf55d1aa11b33f6b819d7fae464acc77701c469c 100644
--- a/tools/build-system/launchpad/sflphone-common-video/debian/control
+++ b/tools/build-system/launchpad/sflphone-common-video/debian/control
@@ -2,7 +2,7 @@ Source: sflphone-common-video
 Maintainer: SavoirFaireLinux Inc <julien.bonjean@savoirfairelinux.com>
 Section: gnome
 Priority: optional
-Build-Depends: debhelper (>= 7.0.50), libgcc1, autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libgsm1-dev, libspeex-dev, libtool, libdbus-1-dev, libasound2-dev, libspeexdsp-dev, uuid-dev, libexpat1-dev, libzrtpcpp-dev, libssl-dev, libpcre3-dev, libyaml-dev, libdbus-c++-dev, libavcodec-dev, libavformat-dev, libswscale-dev, libavdevice-dev, libavutil-dev, libudev-dev
+Build-Depends: debhelper (>= 7.0.50), libgcc1, autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libgsm1-dev, libspeex-dev, libtool, libdbus-1-dev, libasound2-dev, libspeexdsp-dev, uuid-dev, libexpat1-dev, libzrtpcpp-dev, libssl-dev, libpcre3-dev, libyaml-dev, libdbus-c++-dev, libsndfile1-dev, libavcodec-dev, libavformat-dev, libswscale-dev, libavdevice-dev, libavutil-dev, libudev-dev
 Standards-Version: 3.7.3
 
 Package: sflphone-common-video
diff --git a/tools/build-system/launchpad/sflphone-common/debian/control b/tools/build-system/launchpad/sflphone-common/debian/control
index 48ee9496116bb6b08d620a9ff51672c7fe80c1c9..5ba6ab5d4876643e164b1d208cd37c645ffa7e4a 100644
--- a/tools/build-system/launchpad/sflphone-common/debian/control
+++ b/tools/build-system/launchpad/sflphone-common/debian/control
@@ -2,7 +2,7 @@ Source: sflphone-common
 Maintainer: SavoirFaireLinux Inc <julien.bonjean@savoirfairelinux.com>
 Section: gnome
 Priority: optional
-Build-Depends: debhelper (>= 7.0.50), libgcc1, autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libgsm1-dev, libspeex-dev, libtool, libdbus-1-dev, libasound2-dev, libspeexdsp-dev, uuid-dev, libexpat1-dev, libzrtpcpp-dev, libssl-dev, libpcre3-dev, libyaml-dev, libdbus-c++-dev
+Build-Depends: debhelper (>= 7.0.50), libgcc1, autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libgsm1-dev, libspeex-dev, libtool, libdbus-1-dev, libasound2-dev, libspeexdsp-dev, uuid-dev, libexpat1-dev, libzrtpcpp-dev, libssl-dev, libpcre3-dev, libyaml-dev, libdbus-c++-dev, libsndfile1-dev
 Standards-Version: 3.7.3
 
 Package: sflphone-common
diff --git a/tools/build-system/rpm/sflphone.spec b/tools/build-system/rpm/sflphone.spec
new file mode 100644
index 0000000000000000000000000000000000000000..c38d86010773c487baf126a0e5022509272c8bf3
--- /dev/null
+++ b/tools/build-system/rpm/sflphone.spec
@@ -0,0 +1,303 @@
+%bcond_with video
+Name:           sflphone
+Version:        1.2.3
+Release:        1%{?dist}
+Summary:        SIP/IAX2 compatible enterprise-class software phone
+Group:          Applications/Internet
+License:        GPLv3
+URL:            http://sflphone.org/
+Source0:        https://projects.savoirfairelinux.com/attachments/download/6423/%{name}-%{version}.tar.gz
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildRequires:      gettext openssl-devel desktop-file-utils perl
+BuildRequires:      libyaml-devel alsa-lib-devel pulseaudio-libs-devel
+BuildRequires:      ccrtp-devel libzrtpcpp-devel dbus-c++-devel pcre-devel
+BuildRequires:      gsm-devel speex-devel expat-devel libsamplerate-devel
+BuildRequires:      gnome-doc-utils libtool libsexy-devel intltool yelp-tools
+BuildRequires:      libnotify-devel check-devel rarian-compat ilbc-devel
+BuildRequires:      evolution-data-server-devel gnome-common libsndfile-devel
+# KDE requires
+BuildRequires:      cmake kdepimlibs-devel
+%if 0%{?fedora} > 18
+BuildRequires:      perl-podlators
+%endif
+%if %{with video} && 0%{?fedora} < 18
+BuildRequires:      libudev-devel
+%endif
+%if %{with video} && 0%{?fedora} >= 18
+BuildRequires:      systemd-devel
+%endif
+
+%description
+SFLphone is a robust standards-compliant enterprise software phone,
+for desktop and embedded systems. It is designed to handle
+several hundreds of calls a day. It supports both SIP and IAX2
+protocols.
+
+%prep
+%setup -q
+
+%build
+# Compile the daemon
+pushd daemon
+./autogen.sh
+# Compile pjproject first
+pushd libs
+./compile_pjsip.sh
+popd
+# Compile daemon
+%if %{with video}
+%configure --enable-video
+%else
+%configure
+%endif
+make %{?_smp_mflags}
+make doc
+popd
+pushd plugins
+./autogen.sh
+%configure
+make %{?_smp_mflags}
+popd
+# Compile kde client (only without video)
+%if ! %{with video}
+pushd kde
+sed -i '/^[^#]add_subdirectory.*test/s/^[^#]/#/' src/CMakeLists.txt
+./config.sh --prefix=%{_prefix}
+cd build
+make %{?_smp_mflags}
+popd
+%endif
+# Compile gnome client
+pushd gnome
+./autogen.sh
+%if %{with video}
+%configure --enable-video
+%else
+%configure
+%endif
+make %{?_smp_mflags}
+popd
+
+
+%if %{with video}
+%package gnome-video
+Summary:        SIP/IAX2 compatible enterprise-class software phone
+Group:          Applications/Internet
+Requires:       %{name}-common-video
+Conflicts:      sflphone-gnome sflphone
+BuildRequires:  ffmpeg-devel clutter-gtk-devel
+%description gnome-video
+SFLphone is a robust standards-compliant enterprise software phone,
+for desktop and embedded systems. It is designed to handle
+several hundreds of calls a day. It supports both SIP and IAX2
+protocols.
+
+This package includes the Gnome client with videoconferencing ability
+
+%package common-video
+Summary:        SIP/IAX2 compatible enterprise-class software phone
+Group:          Applications/Internet
+Conflicts: sflphone sflphone-daemon sflphone-common
+%description common-video
+SFLphone is a robust standards-compliant enterprise software phone,
+for desktop and embedded systems. It is designed to handle
+several hundreds of calls a day. It supports both SIP and IAX2
+protocols.
+
+This package includes the SFLPhone daemon with videoconferencing enabled
+%else
+%package common
+Summary:        SIP/IAX2 compatible enterprise-class software phone
+Group:          Applications/Internet
+Conflicts: sflphone sflphone-daemon-video
+%description common
+SFLphone is a robust standards-compliant enterprise software phone,
+for desktop and embedded systems. It is designed to handle
+several hundreds of calls a day. It supports both SIP and IAX2
+protocols.
+
+This package includes the SFLPhone common
+
+%package gnome
+Summary:        Gnome interface for SFLphone
+Group:          Applications/Internet
+Requires:       %{name}-common
+Obsoletes:      sflphone < 1.2.2-2
+Conflicts:      sflphone-video
+%description gnome
+SFLphone is a robust standards-compliant enterprise software phone,
+for desktop and embedded systems. It is designed to handle
+several hundreds of calls a day. It supports both SIP and IAX2
+protocols.
+
+This package includes the Gnome client
+
+
+%package kde
+Summary:        KDE interface for SFLphone
+Group:          Applications/Internet
+Requires:       %{name}-common
+%description kde
+SFLphone is a robust standards-compliant enterprise software phone,
+for desktop and embedded systems. It is designed to handle
+several hundreds of calls a day. It supports both SIP and IAX2
+protocols.
+
+This package includes the KDE client
+%endif
+
+%package plugins
+Summary:        Plugins (address book) for SFLphone
+Group:          Applications/Internet
+Requires:       %{name}-common
+%description plugins
+SFLphone is a robust standards-compliant enterprise software phone,
+for desktop and embedded systems. It is designed to handle
+several hundreds of calls a day. It supports both SIP and IAX2
+protocols.
+
+This package includes the address book plugin.
+
+
+%install
+rm -rf %{buildroot}
+pushd daemon
+make install DESTDIR=$RPM_BUILD_ROOT
+popd
+# Gnome install
+pushd gnome
+make install DESTDIR=$RPM_BUILD_ROOT
+# Find Lang files
+popd
+# Plugins install
+pushd plugins
+make install DESTDIR=$RPM_BUILD_ROOT
+popd
+%find_lang sflphone --with-gnome
+# Handling desktop file
+desktop-file-validate %{buildroot}%{_datadir}/applications/%{name}.desktop
+%if ! %{with video}
+# KDE install
+pushd kde/build
+make install DESTDIR=$RPM_BUILD_ROOT
+popd
+%endif
+
+%if %{with video}
+%pre gnome-video
+if [ "$1" -gt 1 ] ; then
+    glib-compile-schemas %{_datadir}/glib-2.0/schemas &>/dev/null
+fi
+
+%post gnome-video
+    glib-compile-schemas %{_datadir}/glib-2.0/schemas &>/dev/null
+
+%preun gnome-video
+if [ "$1" -eq 0 ] ; then
+    glib-compile-schemas %{_datadir}/glib-2.0/schemas &>/dev/null
+fi
+%else
+%pre gnome
+if [ "$1" -gt 1 ] ; then
+    glib-compile-schemas %{_datadir}/glib-2.0/schemas &>/dev/null
+fi
+
+%post gnome
+    glib-compile-schemas %{_datadir}/glib-2.0/schemas &>/dev/null
+
+%preun gnome
+if [ "$1" -eq 0 ] ; then
+    glib-compile-schemas %{_datadir}/glib-2.0/schemas &>/dev/null
+fi
+%endif
+
+%if %{with video}
+%files common-video
+%else
+%files common
+%endif
+%defattr(-,root,root,-)
+%doc AUTHORS COPYING NEWS README
+%{_libdir}/%{name}/*
+%{_datadir}/dbus-1/services/org.%{name}.SFLphone.service
+%{_mandir}/man1/sflphoned.1.gz*
+%{_datadir}/pixmaps/%{name}.svg
+%{_datadir}/%{name}/*
+
+%if %{with video}
+%files -f sflphone.lang gnome-video
+%else
+%files -f sflphone.lang gnome
+%endif
+%defattr(-,root,root,-)
+%{_bindir}/sflphone
+%{_bindir}/sflphone-client-gnome
+%{_datadir}/glib-2.0/schemas/org.sflphone.SFLphone.gschema.xml
+%{_datadir}/applications/%{name}.desktop
+%{_mandir}/man1/sflphone.1.gz
+%{_mandir}/man1/sflphone-client-gnome.1.gz
+%{_datadir}/pixmaps/%{name}.svg
+%{_datadir}/%{name}/*
+
+%files plugins
+%{_libdir}/sflphone/plugins/libevladdrbook.so
+
+%if ! %{with video}
+%files kde
+%{_bindir}/sflphone-client-kde
+%{_datadir}/kde4/apps/sflphone-client-kde
+%{_datadir}/kde4/apps/plasma/plasmoids/
+%{_datadir}/kde4/apps/plasma/services/sflphone.operations
+%{_datadir}/kde4/services
+%{_datadir}/config.kcfg/sflphone-client-kde.kcfg
+%{_datadir}/applications/kde4
+%doc %{_datadir}/doc/HTML/*/sflphone-client-kde
+%doc %{_mandir}/man1/*kde*
+%{_datadir}/icons/hicolor
+%{_libdir}/libksflphone.so*
+%{_libdir}/libqtsflphone.so*
+%{_libdir}/kde4/plasma_engine_sflphone.so
+%exclude %{_includedir}/kde4/ksflphone/*.h
+%exclude %{_includedir}/kde4/qtsflphone/*.h
+%endif
+
+%changelog
+* Wed Jun 19 2013 Simon Piette <simonp@fedoraproject.org> - 1.2.3-1
+- Update to 1.2.3
+- Enable ilbc
+
+* Mon Feb 18 2013 Simon Piette <simonp@fedoraproject.org> - 1.2.2-6
+- Add sflphone-plugins
+
+* Mon Feb 18 2013 Simon Piette <simonp@fedoraproject.org> - 1.2.2-5
+- Renamed daemon to config
+
+* Mon Feb 18 2013 Simon Piette <simonp@fedoraproject.org> - 1.2.2-4
+- Video variant for gnome
+
+* Wed Feb 13 2013 Simon Piette <simonp@fedoraproject.org> - 1.2.2-3
+- split daemon and gnome packages
+
+* Wed Feb 13 2013 Simon Piette <simonp@fedoraproject.org> - 1.2.2-2
+- creates a kde client package
+
+* Tue Jan 15 2013 Simon Piette <simonp@fedoraproject.org> - 1.2.2-1
+- upgraded to 1.2.2
+- updated BuildRequires
+- disabled ilbc
+- replaced gconf with gsettings
+
+* Tue Sep 11 2012 Simon Piette <simonp@fedoraproject.org> - 1.2.0-1
+- upgraded to 1.2.0 (tested on f16)
+- updated BuildRequires
+
+* Wed Apr 20 2011 Prabin Kumar Datta <prabindatta@fedoraproject.org> - 0.9.13-1
+- avoiding compling with Celt codec support to resolve build problem
+- removed clean section since not required
+- upgraded to 0.9.13
+
+* Mon Apr 18 2011 Prabin Kumar Datta <prabindatta@fedoraproject.org> - 0.9.12-2
+- Fixed schema registration problem
+
+* Fri Mar 25 2011 Prabin Kumar Datta <prabindatta@fedoraproject.org> - 0.9.12-1
+- Initial build
diff --git a/tools/build-system/setenv.sh b/tools/build-system/setenv.sh
index b78df319f47a87a601e41c09836e2ee124b7ae26..f8bc9ec302ab112c9f7e6dd27fef6e247fcafeb5 100644
--- a/tools/build-system/setenv.sh
+++ b/tools/build-system/setenv.sh
@@ -22,5 +22,5 @@ export REFERENCE_REPOSITORY="${ROOT_DIR}/sflphone-source-repository"
 
 export WORKING_DIR="${ROOT_DIR}/sflphone-build-repository/tools/build-system"
 export LAUNCHPAD_DIR="${WORKING_DIR}/launchpad"
-LAUNCHPAD_DISTRIBUTIONS=("oneiric" "precise" "quantal" "raring")
+LAUNCHPAD_DISTRIBUTIONS=("oneiric" "precise" "quantal" "raring" "saucy")
 export LAUNCHPAD_DISTRIBUTIONS