diff --git a/Main/AndroidManifest.xml b/Main/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..469d946b244483a40efd63ff2184b264812ae0b4
--- /dev/null
+++ b/Main/AndroidManifest.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="gr.grnet.academicid.inspector"
+          android:versionCode="1"
+          android:versionName="1.0">
+    <uses-sdk android:minSdkVersion="8"
+              android:targetSdkVersion="16"/>
+
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.CAMERA"/>
+    <uses-permission android:name="android.permission.INTERNET"/>
+
+    <uses-feature android:name="android.hardware.camera" android:required="false"/>
+    <uses-feature android:name="android.hardware.camera.autofocus"/>
+
+
+    <application android:label="@string/app_name"
+                 android:name="InspectorApplication"
+                 android:icon="@drawable/ic_launcher"
+                 android:allowBackup="true">
+        <activity android:name="MainActivity"
+                  android:label="@string/app_name"
+                  android:screenOrientation="portrait"
+                  android:configChanges="keyboardHidden|orientation"
+                  android:windowSoftInputMode="stateHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+        <activity android:name=".InspectionResults"
+                  android:screenOrientation="portrait"
+                  android:configChanges="keyboardHidden|orientation"
+                  android:windowSoftInputMode="stateHidden"/>
+        <activity android:name=".ScanQR"
+                  android:screenOrientation="portrait"
+                  android:configChanges="keyboardHidden|orientation"/>
+        <activity android:name="com.dm.zbar.android.scanner.ZBarScannerActivity"
+                  android:screenOrientation="portrait"
+                  android:configChanges="keyboardHidden|orientation"/>
+        <activity android:name=".Preferences"
+                  android:screenOrientation="portrait"
+                  android:configChanges="keyboardHidden|orientation"/>
+        <activity android:name=".ChangePassword"
+                  android:screenOrientation="portrait"
+                  android:configChanges="keyboardHidden|orientation"
+                  android:windowSoftInputMode="stateHidden"/>
+    </application>
+</manifest> 
\ No newline at end of file
diff --git a/Main/gen/gr/grnet/academicid/inspector/BuildConfig.java b/Main/gen/gr/grnet/academicid/inspector/BuildConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..0dc2e2afb309396a9bfb1193ba4fc0b4d6b41c30
--- /dev/null
+++ b/Main/gen/gr/grnet/academicid/inspector/BuildConfig.java
@@ -0,0 +1,8 @@
+/*___Generated_by_IDEA___*/
+
+package gr.grnet.academicid.inspector;
+
+/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
+public final class BuildConfig {
+  public final static boolean DEBUG = Boolean.parseBoolean(null);
+}
\ No newline at end of file
diff --git a/Main/gen/gr/grnet/academicid/inspector/Manifest.java b/Main/gen/gr/grnet/academicid/inspector/Manifest.java
new file mode 100644
index 0000000000000000000000000000000000000000..037103ecf20bc18fbe316217d92e2c8085f3854a
--- /dev/null
+++ b/Main/gen/gr/grnet/academicid/inspector/Manifest.java
@@ -0,0 +1,7 @@
+/*___Generated_by_IDEA___*/
+
+package gr.grnet.academicid.inspector;
+
+/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
+public final class Manifest {
+}
\ No newline at end of file
diff --git a/Main/gen/gr/grnet/academicid/inspector/R.java b/Main/gen/gr/grnet/academicid/inspector/R.java
new file mode 100644
index 0000000000000000000000000000000000000000..6d597e6094ed7e1da995ac0275766588d9afc3ec
--- /dev/null
+++ b/Main/gen/gr/grnet/academicid/inspector/R.java
@@ -0,0 +1,7 @@
+/*___Generated_by_IDEA___*/
+
+package gr.grnet.academicid.inspector;
+
+/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
+public final class R {
+}
\ No newline at end of file
diff --git a/Main/res/drawable-hdpi/action_search.png b/Main/res/drawable-hdpi/action_search.png
new file mode 100644
index 0000000000000000000000000000000000000000..f12e005ebe835c1dd2f6ae324224c3ee296d2d68
Binary files /dev/null and b/Main/res/drawable-hdpi/action_search.png differ
diff --git a/Main/res/drawable-hdpi/action_settings.png b/Main/res/drawable-hdpi/action_settings.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e4580e0534c913abc5560067866b162e2972945
Binary files /dev/null and b/Main/res/drawable-hdpi/action_settings.png differ
diff --git a/Main/res/drawable-hdpi/content_remove.png b/Main/res/drawable-hdpi/content_remove.png
new file mode 100644
index 0000000000000000000000000000000000000000..094eea589246b46e26d3cf02285f26c1abb33700
Binary files /dev/null and b/Main/res/drawable-hdpi/content_remove.png differ
diff --git a/Main/res/drawable-hdpi/grnet_logo.png b/Main/res/drawable-hdpi/grnet_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..bc4e4607c1b14ac1b92e637157e735d0bc219a30
Binary files /dev/null and b/Main/res/drawable-hdpi/grnet_logo.png differ
diff --git a/Main/res/drawable-hdpi/ic_launcher.png b/Main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..feff32f57f603d21e79db3ad7932e09d3efa7790
Binary files /dev/null and b/Main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/Main/res/drawable-ldpi/action_search.png b/Main/res/drawable-ldpi/action_search.png
new file mode 100644
index 0000000000000000000000000000000000000000..587d9e0bf392fc928947f04293ba009f7fc77b29
Binary files /dev/null and b/Main/res/drawable-ldpi/action_search.png differ
diff --git a/Main/res/drawable-ldpi/action_settings.png b/Main/res/drawable-ldpi/action_settings.png
new file mode 100644
index 0000000000000000000000000000000000000000..d3e42edcb6db096d90d1b28a2d4609d3419c5751
Binary files /dev/null and b/Main/res/drawable-ldpi/action_settings.png differ
diff --git a/Main/res/drawable-ldpi/content_remove.png b/Main/res/drawable-ldpi/content_remove.png
new file mode 100644
index 0000000000000000000000000000000000000000..3336760d5f3efdfefefd6899317c3a09264430f6
Binary files /dev/null and b/Main/res/drawable-ldpi/content_remove.png differ
diff --git a/Main/res/drawable-ldpi/grnet_logo.png b/Main/res/drawable-ldpi/grnet_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..bc4e4607c1b14ac1b92e637157e735d0bc219a30
Binary files /dev/null and b/Main/res/drawable-ldpi/grnet_logo.png differ
diff --git a/Main/res/drawable-ldpi/ic_launcher.png b/Main/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..e1959d54fd65e38c346521141a2fb6c4a057da0c
Binary files /dev/null and b/Main/res/drawable-ldpi/ic_launcher.png differ
diff --git a/Main/res/drawable-mdpi/action_search.png b/Main/res/drawable-mdpi/action_search.png
new file mode 100644
index 0000000000000000000000000000000000000000..587d9e0bf392fc928947f04293ba009f7fc77b29
Binary files /dev/null and b/Main/res/drawable-mdpi/action_search.png differ
diff --git a/Main/res/drawable-mdpi/action_settings.png b/Main/res/drawable-mdpi/action_settings.png
new file mode 100644
index 0000000000000000000000000000000000000000..d3e42edcb6db096d90d1b28a2d4609d3419c5751
Binary files /dev/null and b/Main/res/drawable-mdpi/action_settings.png differ
diff --git a/Main/res/drawable-mdpi/content_remove.png b/Main/res/drawable-mdpi/content_remove.png
new file mode 100644
index 0000000000000000000000000000000000000000..3336760d5f3efdfefefd6899317c3a09264430f6
Binary files /dev/null and b/Main/res/drawable-mdpi/content_remove.png differ
diff --git a/Main/res/drawable-mdpi/grnet_logo.png b/Main/res/drawable-mdpi/grnet_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..bc4e4607c1b14ac1b92e637157e735d0bc219a30
Binary files /dev/null and b/Main/res/drawable-mdpi/grnet_logo.png differ
diff --git a/Main/res/drawable-mdpi/ic_launcher.png b/Main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..e1959d54fd65e38c346521141a2fb6c4a057da0c
Binary files /dev/null and b/Main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/Main/res/drawable-xhdpi/action_search.png b/Main/res/drawable-xhdpi/action_search.png
new file mode 100644
index 0000000000000000000000000000000000000000..3549f84dd8f5e38665849b46e252bc34f29be027
Binary files /dev/null and b/Main/res/drawable-xhdpi/action_search.png differ
diff --git a/Main/res/drawable-xhdpi/action_settings.png b/Main/res/drawable-xhdpi/action_settings.png
new file mode 100644
index 0000000000000000000000000000000000000000..09b01483454788c435acf715c57d92fc0ead0a7c
Binary files /dev/null and b/Main/res/drawable-xhdpi/action_settings.png differ
diff --git a/Main/res/drawable-xhdpi/content_remove.png b/Main/res/drawable-xhdpi/content_remove.png
new file mode 100644
index 0000000000000000000000000000000000000000..f391760ef134adb96dcce85abb2c5ab776f8e6bd
Binary files /dev/null and b/Main/res/drawable-xhdpi/content_remove.png differ
diff --git a/Main/res/drawable-xhdpi/grnet_logo.png b/Main/res/drawable-xhdpi/grnet_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..bc4e4607c1b14ac1b92e637157e735d0bc219a30
Binary files /dev/null and b/Main/res/drawable-xhdpi/grnet_logo.png differ
diff --git a/Main/res/drawable-xhdpi/ic_launcher.png b/Main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..77dfe95250ab670b172afa695a08658776a91ebb
Binary files /dev/null and b/Main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/Main/res/layout/change_password.xml b/Main/res/layout/change_password.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aa42507bad1a692f9b44114575852762d6e506f8
--- /dev/null
+++ b/Main/res/layout/change_password.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+    <LinearLayout
+            android:orientation="vertical"
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent">
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="30dp"
+                android:layout_marginBottom="3dp"
+                android:layout_marginLeft="50dp"
+                android:text="@string/lbl_current_password"/>
+        <EditText
+                android:id="@+id/etxt_current_password"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="40dp"
+                android:layout_marginRight="40dp"
+                android:contentDescription="@null"
+                android:inputType="textPassword"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="40dp"
+                android:layout_marginBottom="3dp"
+                android:layout_marginLeft="50dp"
+                android:text="@string/lbl_new_password"/>
+        <EditText
+                android:id="@+id/etxt_new_password"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="40dp"
+                android:layout_marginRight="40dp"
+                android:contentDescription="@null"
+                android:inputType="textPassword"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:layout_marginBottom="3dp"
+                android:layout_marginLeft="50dp"
+                android:text="@string/lbl_new_password_confirmation"/>
+        <EditText
+                android:id="@+id/etxt_new_password_confirmation"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="40dp"
+                android:layout_marginRight="40dp"
+                android:contentDescription="@null"
+                android:inputType="textPassword"/>
+        <LinearLayout
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_marginTop="30dp"
+                android:layout_marginLeft="15dp"
+                android:layout_marginRight="15dp">
+            <Button
+                    android:id="@+id/btn_cancel"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginRight="3dp"
+                    android:text="@string/lbl_cancel"
+                    android:onClick="cancel"/>
+            <Button
+                    android:id="@+id/btn_confirm"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="3dp"
+                    android:text="@string/lbl_confirm"
+                    android:onClick="confirm"/>
+        </LinearLayout>
+    </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/Main/res/layout/inspection_results.xml b/Main/res/layout/inspection_results.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0b895f26518046f0c4aab3478dde6ae404f68762
--- /dev/null
+++ b/Main/res/layout/inspection_results.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:padding="10dp">
+    <ScrollView
+            android:id="@+id/scrollView"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:fillViewport="true">
+        <RelativeLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center_horizontal">
+            <TextView
+                    android:id="@+id/txtv_inspection_result"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_centerHorizontal="true"
+                    android:visibility="gone"
+                    android:layout_marginBottom="5dp"/>
+            <TextView
+                    android:id="@+id/lbl_serial_number"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginBottom="5dp"
+                    style="@style/label"
+                    android:layout_below="@id/txtv_inspection_result"
+                    android:visibility="gone"
+                    android:text="@string/lbl_serial_no"/>
+            <TextView
+                    android:id="@+id/txtv_serial_number"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginBottom="5dp"
+                    android:layout_below="@id/lbl_serial_number"
+                    android:visibility="gone"
+                    style="@style/view_text"/>
+
+            <TextView
+                    android:id="@+id/lbl_concat_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginBottom="5dp"
+                    style="@style/label"
+                    android:layout_below="@id/txtv_serial_number"
+                    android:visibility="gone"
+                    android:text="@string/lbl_name"/>
+
+            <TextView
+                    android:id="@+id/txtv_concat_name"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginBottom="5dp"
+                    android:layout_below="@id/lbl_concat_name"
+                    android:visibility="gone"
+                    style="@style/view_text"/>
+
+            <TextView
+                    android:id="@+id/lbl_university"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginBottom="5dp"
+                    style="@style/label"
+                    android:layout_below="@id/txtv_concat_name"
+                    android:visibility="gone"
+                    android:text="@string/lbl_university"/>
+
+            <TextView
+                    android:id="@+id/txtv_university"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginBottom="5dp"
+                    android:layout_below="@id/lbl_university"
+                    android:visibility="gone"
+                    style="@style/view_text"/>
+
+            <TextView
+                    android:id="@+id/lbl_residence"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginBottom="5dp"
+                    style="@style/label"
+                    android:layout_below="@id/txtv_university"
+                    android:visibility="gone"
+                    android:text="@string/lbl_residence"/>
+
+            <TextView
+                    android:id="@+id/txtv_residence"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginBottom="5dp"
+                    android:layout_below="@id/lbl_residence"
+                    android:visibility="gone"
+                    style="@style/view_text"/>
+
+            <TextView
+                    android:id="@+id/lbl_inspection_description"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginBottom="5dp"
+                    android:layout_below="@id/txtv_residence"
+                    android:text="@string/lbl_errorCode"
+                    android:visibility="gone"/>
+
+            <TextView
+                    android:id="@+id/txtv_inspection_description"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginBottom="5dp"
+                    android:layout_below="@id/lbl_inspection_description"
+                    style="@style/view_text"
+                    android:visibility="gone"/>
+            <TextView
+                    android:id="@+id/lbl_init_message"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_centerHorizontal="true"
+                    android:layout_centerVertical="true"
+                    android:textStyle="bold|italic"
+                    style="@style/view_text"
+                    android:text="@string/lbl_init_message"/>
+        </RelativeLayout>
+    </ScrollView>
+
+    <Button
+            android:id="@+id/btn_scan_qr"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:text="@string/lbl_scan_qr"
+            android:onClick="scanQR"/>
+    <RelativeLayout
+            android:id="@+id/rellay_serial_input"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="5dp">
+        <ImageButton
+                android:id="@+id/btn_check_serial"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:contentDescription="@null"
+                android:src="@drawable/action_search"
+                android:onClick="checkSerialNo"/>
+        <EditText
+                android:id="@+id/etxt_serial_number"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_toLeftOf="@id/btn_check_serial"
+                android:layout_toRightOf="@+id/btn_clear_serial"
+                android:layout_alignBottom="@id/btn_check_serial"
+                android:layout_marginTop="4dp"
+                android:imeOptions="actionDone"
+                android:inputType="number"
+                android:maxLength="12"
+                android:hint="@string/lbl_enter_serial"/>
+        <ImageButton
+                android:id="@+id/btn_clear_serial"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:contentDescription="@null"
+                android:src="@drawable/content_remove"
+                android:onClick="clearContent"/>
+    </RelativeLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/Main/res/layout/main.xml b/Main/res/layout/main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cab03eceb25f4d89b14e8af8ef844100214ac6da
--- /dev/null
+++ b/Main/res/layout/main.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+    <LinearLayout
+            android:orientation="vertical"
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent">
+        <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:contentDescription="@null"
+                android:src="@drawable/ic_launcher" android:layout_gravity="center_horizontal"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="30dp"
+                android:layout_marginBottom="3dp"
+                android:layout_marginLeft="50dp"
+                android:text="@string/lbl_username"/>
+        <EditText
+                android:id="@+id/etxt_username"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="40dp"
+                android:layout_marginRight="40dp"
+                android:inputType="text|textNoSuggestions"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:layout_marginBottom="3dp"
+                android:layout_marginLeft="50dp"
+                android:text="@string/lbl_password"/>
+        <EditText
+                android:id="@+id/etxt_password"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="40dp"
+                android:layout_marginRight="40dp"
+                android:inputType="textPassword"/>
+        <Button
+                android:id="@+id/btn_sign_in"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:layout_marginTop="10dp"
+                android:text="@string/lbl_sign_in"
+                android:onClick="signIn"/>
+    </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/Main/res/menu/menu_application.xml b/Main/res/menu/menu_application.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8ead7fa6d820cae9c69ebdd3168c97fa7f552c3b
--- /dev/null
+++ b/Main/res/menu/menu_application.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+            android:id="@+id/menu_settings"
+            android:icon="@drawable/action_settings"
+            android:title="@string/menu_settings"/>
+</menu>
\ No newline at end of file
diff --git a/Main/res/values-el/strings.xml b/Main/res/values-el/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4568dcfa7dd7be7c5881582755b9904b24d363b4
--- /dev/null
+++ b/Main/res/values-el/strings.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">Academic ID Inspector</string>
+
+    <string name="lbl_username">Όνομα Χρήστη:</string>
+    <string name="lbl_password">Κωδικός Πρόσβασης:</string>
+    <string name="lbl_sign_in">Είσοδος</string>
+
+    <string name="msg_wait">Παρακαλώ περιμένετε…</string>
+    <string name="msg_incorrect_credentials">Το όνομα Χρήστη ή ο Κωδικός Πρόσβασης είναι εσφαλμένα</string>
+    <string name="msg_no_camera_available">Η κάμερα δεν είναι διαθέσιμη</string>
+
+    <string name="title_no_net_available">Δίκτυο μη Διαθέσιμο</string>
+    <string name="msg_no_net_available">Για ενεργοποίηση πιέστε Επόμενο</string>
+    <string name="action_next">Επόμενο</string>
+    <string name="action_close">Τερματισμός</string>
+
+    <string name="lbl_init_message">Σαρώστε τον κωδικό QR ή εισάγετε τον σειριακό αριθμό</string>
+    <string name="lbl_scan_qr">Σάρωση QR</string>
+    <string name="lbl_enter_serial">Εισαγωγή Σειριακού Αρ.</string>
+    <string name="lbl_exit">Πιέστε ξανά για έξοδο</string>
+
+    <string name="lbl_valid">ΕΓΚΥΡΟ</string>
+    <string name="lbl_invalid">ΑΚΥΡΟ</string>
+    <string name="lbl_serial_no">Σειριακός Αριθμός:</string>
+    <string name="lbl_name">Όνομα:</string>
+    <string name="lbl_university">Έδρα Σχολής:</string>
+    <string name="lbl_residence">Κάτοικος:</string>
+    <string name="lbl_errorCode">Αιτιολογία:</string>
+
+    <string name="msg_invalid_input">Το στοιχείο εισόδου δεν αντιστοιχεί σε έγκυρη ακαδημαϊκή ταυτότητα</string>
+    <string name="msg_error_inspecting_academicId">Παρουσιάστηκε σφάλμα κατά την επιθεώρησης της ακαδημαϊκής ταυτότητας</string>
+
+    <string name="menu_settings">Ρυθμίσεις</string>
+
+    <string name="title_change_password">Αλλαγή Κωδικού Πρόσβασης</string>
+    <string name="msg_change_password">Αλλαγή του κωδικού πρόσβασης του χρήστη</string>
+
+    <string name="lbl_current_password">Τρέχων Κωδικός Πρόσβασης:</string>
+    <string name="lbl_new_password">Νέος Κωδικός Πρόσβασης:</string>
+    <string name="lbl_new_password_confirmation">Επιβεβαίωση Νέου Κωδικού:</string>
+    <string name="lbl_cancel">Ακύρωση</string>
+    <string name="lbl_confirm">Επιβεβαίωση</string>
+
+    <string name="msg_password_change_required">Απαιτείται αλλαγή του κωδικού πρόσβασης</string>
+    <string name="msg_incorrect_current_password">Ο τρέχων κωδικός πρόσβασης είναι λάθος</string>
+    <string name="msg_new_passwords_dont_match">Οι νέοι κωδικοί πρόσβασης δεν είναι ίδιοι</string>
+    <string name="msg_password_too_short">Ο κωδικός πρόσβασης πρέπει να περιέχει τουλάχιστον 4 χαρακτήρες</string>
+    <string name="msg_new_current_password_same">Ο νέος και ο τρέχον κωδικός πρόσβασης δεν πρέπει να είναι ίδιοι</string>
+    <string name="msg_error_changing_password">Παρουσιάστηκε σφάλμα κατα την διαδικασία αποθήκευσης του νέου κωδικού πρόσβασης</string>
+</resources>
\ No newline at end of file
diff --git a/Main/res/values/strings.xml b/Main/res/values/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3d956f57c5c9e3a79cecea9ea30e7aefee393c06
--- /dev/null
+++ b/Main/res/values/strings.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">Academic ID Inspector</string>
+
+    <string name="lbl_username">Username:</string>
+    <string name="lbl_password">Password:</string>
+    <string name="lbl_sign_in">Sign In</string>
+
+    <string name="msg_wait">Please wait…</string>
+    <string name="msg_incorrect_credentials">Incorrect username or password</string>
+    <string name="msg_no_camera_available">Rear Facing Camera Unavailable</string>
+
+    <string name="title_no_net_available">No Network Connection</string>
+    <string name="msg_no_net_available">To enable network connection touch Next</string>
+    <string name="action_next">Next</string>
+    <string name="action_close">Close</string>
+
+    <string name="lbl_init_message">Scan QR code or enter serial number</string>
+    <string name="lbl_scan_qr">Scan QR Code</string>
+    <string name="lbl_enter_serial">Enter Serial Number</string>
+    <string name="lbl_exit">Press again to exit</string>
+
+    <string name="lbl_valid">VALID</string>
+    <string name="lbl_invalid">INVALID</string>
+    <string name="lbl_serial_no">Serial Number:</string>
+    <string name="lbl_name">Name:</string>
+    <string name="lbl_university">University Location:</string>
+    <string name="lbl_residence">Resident:</string>
+    <string name="lbl_errorCode">Reason:</string>
+
+    <string name="msg_invalid_input">Input is not a valid Academic ID</string>
+    <string name="msg_error_inspecting_academicId">Error trying to inspect academic ID</string>
+
+    <string name="menu_settings">Settings</string>
+
+    <string name="title_change_password">Change Password</string>
+    <string name="msg_change_password">Change the user password</string>
+
+    <string name="lbl_current_password">Current Password:</string>
+    <string name="lbl_new_password">New Password:</string>
+    <string name="lbl_new_password_confirmation">Confirm New Password:</string>
+    <string name="lbl_cancel">Cancel</string>
+    <string name="lbl_confirm">Confirm</string>
+
+    <string name="msg_password_change_required">Password changed required</string>
+    <string name="msg_incorrect_current_password">Current password is incorrect</string>
+    <string name="msg_new_passwords_dont_match">The new passwords don\'t match</string>
+    <string name="msg_password_too_short">Password must contain at least 4 characters</string>
+    <string name="msg_new_current_password_same">New and current password should not be the same</string>
+    <string name="msg_error_changing_password">Error trying to update user password</string>
+</resources>
\ No newline at end of file
diff --git a/Main/res/values/styles.xml b/Main/res/values/styles.xml
new file mode 100644
index 0000000000000000000000000000000000000000..acec8756c6e83bcb0adf67840dbc15ed6c0a1c8d
--- /dev/null
+++ b/Main/res/values/styles.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="intro_blurb_green">
+        <item name="android:textSize">30sp</item>
+        <item name="android:textColor">#00ff00</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+
+	<style name="intro_blurb_orange">
+		<item name="android:textSize">30sp</item>
+		<item name="android:textColor">#ee7620</item>
+		<item name="android:textStyle">bold</item>
+	</style>
+
+	<style name="label">
+		<item name="android:textSize">20sp</item>
+		<item name="android:textColor">#ffffff</item>
+	</style>
+
+    <style name="label_orange">
+        <item name="android:textSize">20sp</item>
+        <item name="android:textColor">#ee7620</item>
+    </style>
+
+	<style name="view_text">
+		<item name="android:textSize">16sp</item>
+		<item name="android:textColor">#cccccc</item>
+	</style>
+</resources>
\ No newline at end of file
diff --git a/Main/res/xml/preferences.xml b/Main/res/xml/preferences.xml
new file mode 100644
index 0000000000000000000000000000000000000000..69bb6f48e5620407252b7a1f48ec5ed0bf2e2b5f
--- /dev/null
+++ b/Main/res/xml/preferences.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+    <PreferenceCategory android:title="@string/menu_settings">
+        <PreferenceScreen
+                android:title="@string/title_change_password"
+                android:summary="@string/msg_change_password">
+            <intent android:action="android.intent.action.VIEW"
+                    android:targetPackage="gr.grnet.academicid.inspector"
+                    android:targetClass="gr.grnet.academicid.inspector.ChangePassword"/>
+        </PreferenceScreen>
+    </PreferenceCategory>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/ChangePassword.java b/Main/src/gr/grnet/academicid/inspector/ChangePassword.java
new file mode 100644
index 0000000000000000000000000000000000000000..a30c5b2b3f73721e1cec6e63691d4af82c0e1519
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/ChangePassword.java
@@ -0,0 +1,128 @@
+package gr.grnet.academicid.inspector;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.Toast;
+import gr.grnet.academicid.inspector.domain.Inspector;
+import gr.grnet.academicid.inspector.parser.ChangePasswordResponse;
+import gr.grnet.academicid.inspector.parser.JSONParser;
+import gr.grnet.academicid.inspector.services.ServiceHandler;
+import gr.grnet.academicid.inspector.utilities.Constants;
+import gr.grnet.academicid.inspector.utilities.Tools;
+
+public class ChangePassword extends Activity {
+
+    private EditText etxtCurrentPassword;
+    private EditText etxtNewPassword;
+    private EditText etxtNewPasswordConfirmation;
+
+    private ProgressDialog progressDialog;
+    private Inspector inspector;
+    private String newPasswordHash;
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.change_password);
+
+        etxtCurrentPassword = (EditText) findViewById(R.id.etxt_current_password);
+        etxtNewPassword = (EditText) findViewById(R.id.etxt_new_password);
+        etxtNewPasswordConfirmation = (EditText) findViewById(R.id.etxt_new_password_confirmation);
+
+        inspector = InspectorApplication.getInspector();
+        if (inspector.shouldChangePswAtLogin())
+            Toast.makeText(getApplicationContext(), getString(R.string.msg_password_change_required), Toast.LENGTH_LONG).show();
+    }
+
+    public void cancel(View view) {
+        finish();
+    }
+
+    public void confirm(View view) {
+        // After 'Sign In' button is pressed, hide soft keyboard
+        InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+        if (getCurrentFocus() != null)
+            inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+
+        String currentPasswordHash = Tools.getHash(etxtCurrentPassword.getText().toString());
+        String newPassword = etxtNewPassword.getText().toString();
+        newPasswordHash = Tools.getHash(newPassword);
+        String newPasswordConfirmationHash = Tools.getHash(etxtNewPasswordConfirmation.getText().toString());
+
+        inspector = InspectorApplication.getInspector();
+
+        // Check if the Current password is the actual password of the user by comparing the hash values.
+        if (!inspector.getPasswordHash().equals(currentPasswordHash)) {
+            Toast.makeText(getApplicationContext(), getString(R.string.msg_incorrect_current_password), Toast.LENGTH_SHORT).show();
+        }
+        // Check if the new password and the new password confirmation match by comparing the hash values.
+        else if (!newPasswordHash.equals(newPasswordConfirmationHash)) {
+            Toast.makeText(getApplicationContext(), getString(R.string.msg_new_passwords_dont_match), Toast.LENGTH_SHORT).show();
+        }
+        // Check if new password is at least 4 chars long.
+        else if (newPassword.length() < 4) {
+            Toast.makeText(getApplicationContext(), getString(R.string.msg_password_too_short), Toast.LENGTH_SHORT).show();
+        }
+        // Check if new password is the same with current password by comparing the hash values.
+        else if (currentPasswordHash.equals(newPasswordHash)) {
+            Toast.makeText(getApplicationContext(), getString(R.string.msg_new_current_password_same), Toast.LENGTH_SHORT).show();
+        } else {
+            new UpdatePassword().execute(inspector.getUsername(), inspector.getPasswordHash(), newPasswordHash);
+        }
+    }
+
+    private class UpdatePassword extends AsyncTask<String, Void, String> {
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+            // Showing progress dialog
+            progressDialog = new ProgressDialog(ChangePassword.this);
+            progressDialog.setMessage(getString(R.string.msg_wait));
+            progressDialog.setCancelable(false);
+            progressDialog.show();
+        }
+
+        @Override
+        protected String doInBackground(String... variables) {
+            return ServiceHandler.makeChangePswCall(variables[0], variables[1], variables[2]);
+        }
+
+        @Override
+        protected void onPostExecute(String result) {
+            super.onPostExecute(result);
+            // Dismiss the progress dialog
+            if (progressDialog.isShowing())
+                progressDialog.dismiss();
+
+            ChangePasswordResponse changePasswordResponse = JSONParser.getResultOfUpdatePassword(result);
+
+            if (!changePasswordResponse.isSuccessful()) {
+                Toast.makeText(getApplicationContext(), getString(R.string.msg_error_changing_password), Toast.LENGTH_SHORT).show();
+                Log.e(Constants.LOGTAG, "ChangePassword.UpdatePassword.OnPostExecute(): Web service returned unsuccessfully with errorCode: " + changePasswordResponse.getError());
+            } else {
+                Log.i(Constants.LOGTAG, "ChangePassword.UpdatePassword.OnPostExecute(): User " + inspector.getUsername() + " successfully changed his password.");
+
+                inspector = InspectorApplication.getInspector();
+                boolean userChangedPsw = inspector.shouldChangePswAtLogin();
+                inspector.setPasswordHash(newPasswordHash);
+                inspector.setChangePswAtLogin(false);
+                InspectorApplication.setInspector(inspector);
+
+                if (userChangedPsw)
+                    startActivity(new Intent(ChangePassword.this, InspectionResults.class));
+                else
+                    finish();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/InspectionResults.java b/Main/src/gr/grnet/academicid/inspector/InspectionResults.java
new file mode 100644
index 0000000000000000000000000000000000000000..383ac37d1ee2228c7cee44145e4315feb4e810d1
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/InspectionResults.java
@@ -0,0 +1,265 @@
+package gr.grnet.academicid.inspector;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+import gr.grnet.academicid.inspector.domain.AcademicId;
+import gr.grnet.academicid.inspector.domain.Inspector;
+import gr.grnet.academicid.inspector.parser.InspectAcademicIdResponse;
+import gr.grnet.academicid.inspector.parser.JSONParser;
+import gr.grnet.academicid.inspector.services.ServiceHandler;
+import gr.grnet.academicid.inspector.utilities.Constants;
+import gr.grnet.academicid.inspector.utilities.Tools;
+import org.jetbrains.annotations.NotNull;
+
+public class InspectionResults extends Activity {
+
+    private static final int SCAN_QR = 1;
+    private static final int REFERRAL_QR = 1;
+    private static final int REFERRAL_SERIAL = 2;
+
+    private TextView lblInitMessage;
+    private TextView txtvInspectionResult;
+    private TextView lblSerialNumber;
+    private TextView txtvSerialNumber;
+    private TextView lblConcatName;
+    private TextView txtvConcatName;
+    private TextView lblUniversity;
+    private TextView txtvUniversity;
+    private TextView lblResidence;
+    private TextView txtvResidence;
+    private TextView lblInspectionDescription;
+    private TextView txtvInspectionDescription;
+    private EditText etxtSerialNumber;
+
+    private ProgressDialog progressDialog;
+    private int referral;
+    private boolean doubleBackToExitPressedOnce = false;
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.inspection_results);
+
+        // Assign views to variables
+        lblInitMessage = (TextView) findViewById(R.id.lbl_init_message);
+        txtvInspectionResult = (TextView) findViewById(R.id.txtv_inspection_result);
+
+        lblSerialNumber = (TextView) findViewById(R.id.lbl_serial_number);
+        txtvSerialNumber = (TextView) findViewById(R.id.txtv_serial_number);
+
+        lblConcatName = (TextView) findViewById(R.id.lbl_concat_name);
+        txtvConcatName = (TextView) findViewById(R.id.txtv_concat_name);
+
+        lblUniversity = (TextView) findViewById(R.id.lbl_university);
+        txtvUniversity = (TextView) findViewById(R.id.txtv_university);
+
+        lblResidence = (TextView) findViewById(R.id.lbl_residence);
+        txtvResidence = (TextView) findViewById(R.id.txtv_residence);
+
+        lblInspectionDescription = (TextView) findViewById(R.id.lbl_inspection_description);
+        txtvInspectionDescription = (TextView) findViewById(R.id.txtv_inspection_description);
+
+        etxtSerialNumber = (EditText) findViewById(R.id.etxt_serial_number);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        this.doubleBackToExitPressedOnce = false;
+    }
+
+    // Method called after 'Scan QR' button is pressed
+    public void scanQR(View view) {
+        Intent intent = new Intent(this, ScanQR.class);
+        startActivityForResult(intent, SCAN_QR);
+    }
+
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == SCAN_QR) {
+            if (resultCode == RESULT_OK) {
+                String scanResult = data.getStringExtra(ScanQR.SCAN_RESULT);
+                referral = REFERRAL_QR;
+                validate(scanResult);
+            }
+        }
+    }
+
+    // Method called after 'Magnifier' button is pressed
+    public void checkSerialNo(View view) {
+        // After 'Check Id' button is pressed, hide soft keyboard
+        InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+        if (getCurrentFocus() != null)
+            inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+
+        String input = etxtSerialNumber.getText().toString();
+        referral = REFERRAL_SERIAL;
+        validate(input);
+    }
+
+    // Method called after 'X' button is pressed
+    public void clearContent(View view) {
+        etxtSerialNumber.setText("");
+    }
+
+    private void validate(String academicId) {
+        if ((academicId.length() == 12) && Tools.isNumericValue(academicId)) {
+            Inspector inspector = InspectorApplication.getInspector();
+            new ValidateAcademicId().execute(inspector.getUsername(), inspector.getPasswordHash(), academicId);
+        } else {
+            // Hide most of the views...
+            lblInitMessage.setVisibility(View.GONE);
+            lblSerialNumber.setVisibility(View.GONE);
+            txtvSerialNumber.setVisibility(View.GONE);
+            lblConcatName.setVisibility(View.GONE);
+            txtvConcatName.setVisibility(View.GONE);
+            lblUniversity.setVisibility(View.GONE);
+            txtvUniversity.setVisibility(View.GONE);
+            lblResidence.setVisibility(View.GONE);
+            txtvResidence.setVisibility(View.GONE);
+            lblInspectionDescription.setVisibility(View.GONE);
+
+            if (referral == REFERRAL_QR)
+                etxtSerialNumber.setText("");
+
+            // ... and present only 'Invalid' message and reason
+            txtvInspectionResult.setVisibility(View.VISIBLE);
+            txtvInspectionResult.setTextAppearance(getApplicationContext(), R.style.intro_blurb_orange);
+            txtvInspectionResult.setText(R.string.lbl_invalid);
+
+            txtvInspectionDescription.setVisibility(View.VISIBLE);
+            txtvInspectionDescription.setText(R.string.msg_invalid_input);
+        }
+    }
+
+    private class ValidateAcademicId extends AsyncTask<String, Void, String> {
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+            // Showing progress dialog
+            progressDialog = new ProgressDialog(InspectionResults.this);
+            progressDialog.setMessage(getString(R.string.msg_wait));
+            progressDialog.setCancelable(false);
+            progressDialog.show();
+        }
+
+        @Override
+        protected String doInBackground(String... variables) {
+            return ServiceHandler.makeInspectAcademicIdCall(variables[0], variables[1], variables[2]);
+        }
+
+        @Override
+        protected void onPostExecute(String result) {
+            super.onPostExecute(result);
+            // Dismiss the progress dialog
+            if (progressDialog.isShowing())
+                progressDialog.dismiss();
+
+            InspectAcademicIdResponse inspectAcademicIdResponse = JSONParser.getResultOfInspectAcademicId(result);
+
+            if (!inspectAcademicIdResponse.isSuccessful()) {
+                Toast.makeText(getApplicationContext(), R.string.msg_error_inspecting_academicId, Toast.LENGTH_SHORT).show();
+                Log.e(Constants.LOGTAG, "InspectionResults.ValidateAcademicId.onPostExecute(): Web service returned unsuccessfully with errorCode: " + inspectAcademicIdResponse.getError());
+            } else {
+                AcademicId academicId = inspectAcademicIdResponse.getAcademicId();
+
+                lblInitMessage.setVisibility(View.GONE);
+                txtvInspectionResult.setVisibility(View.VISIBLE);
+
+                lblSerialNumber.setVisibility(View.VISIBLE);
+                txtvSerialNumber.setVisibility(View.VISIBLE);
+                txtvSerialNumber.setText(String.valueOf(academicId.getSerialNumber()));
+
+                lblConcatName.setVisibility(View.VISIBLE);
+                txtvConcatName.setVisibility(View.VISIBLE);
+                txtvConcatName.setText(Tools.concatenateName(academicId));
+
+                lblUniversity.setVisibility(View.VISIBLE);
+                txtvUniversity.setVisibility(View.VISIBLE);
+                txtvUniversity.setText(academicId.getUniversityLocation());
+
+                lblResidence.setVisibility(View.VISIBLE);
+                txtvResidence.setVisibility(View.VISIBLE);
+                txtvResidence.setText(academicId.getResidenceLocation());
+
+                if (referral == REFERRAL_QR)
+                    etxtSerialNumber.setText("");
+
+
+                if (academicId.isPasoValid() != null && academicId.isPasoValid()) { // If Academic Id is eligible as a a discount voucher
+                    // show 'Valid' message...
+                    txtvInspectionResult.setTextAppearance(getApplicationContext(), R.style.intro_blurb_green);
+                    txtvInspectionResult.setText(R.string.lbl_valid);
+
+                    // ... and hide inspection description view (which is empty)
+                    lblInspectionDescription.setVisibility(View.GONE);
+                    txtvInspectionDescription.setVisibility(View.GONE);
+
+                } else { // If academic Id is not eligible as a discount voucher
+                    // show 'Invalid' message...
+                    txtvInspectionResult.setTextAppearance(getApplicationContext(), R.style.intro_blurb_orange);
+                    txtvInspectionResult.setText(R.string.lbl_invalid);
+
+                    if (academicId.thereIsValidationError()) { // ... and if there is a reason why it not valid
+                        // then display it
+                        lblInspectionDescription.setVisibility(View.VISIBLE);
+                        lblInspectionDescription.setTextAppearance(getApplicationContext(), R.style.label_orange);
+
+                        txtvInspectionDescription.setVisibility(View.VISIBLE);
+                        txtvInspectionDescription.setText(academicId.getValidationError());
+                    } else { // or make view invisible
+                        lblInspectionDescription.setVisibility(View.GONE);
+                        txtvInspectionDescription.setVisibility(View.GONE);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.menu_application, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onMenuItemSelected(int featureId, @NotNull MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.menu_settings:
+                startActivity(new Intent(this, Preferences.class));
+                return true;
+            default:
+                return super.onMenuItemSelected(featureId, item);
+        }
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (doubleBackToExitPressedOnce) {
+            Intent intent = new Intent(Intent.ACTION_MAIN);
+            intent.addCategory(Intent.CATEGORY_HOME);
+            startActivity(intent);
+            finish();
+        } else {
+            this.doubleBackToExitPressedOnce = true;
+            Toast.makeText(this, R.string.lbl_exit, Toast.LENGTH_SHORT).show();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/InspectorApplication.java b/Main/src/gr/grnet/academicid/inspector/InspectorApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..3dcbe7169f2c52f97f8a9c99e4ec560db2c6185a
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/InspectorApplication.java
@@ -0,0 +1,48 @@
+package gr.grnet.academicid.inspector;
+
+import android.app.Application;
+import android.content.Context;
+import gr.grnet.academicid.inspector.domain.Inspector;
+import gr.grnet.academicid.inspector.utilities.SharedPrefs;
+
+public class InspectorApplication extends Application {
+
+    private static Context context;
+    private static Inspector inspector;
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    public InspectorApplication() {
+        super();
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        InspectorApplication.context = getApplicationContext();
+    }
+
+    @Override
+    public void onTerminate() {
+        super.onTerminate();
+        SharedPrefs.ClearInspectorFromPrefs();
+    }
+
+    public static Context getAppContext() {
+        return InspectorApplication.context;
+    }
+
+    public static Inspector getInspector() {
+        // Check if object has been deleted from Android garbage collector and if it has, recall it from Shared Preferences
+        if (inspector == null) {
+            inspector = SharedPrefs.getInspectorFromPrefs();
+        }
+        return inspector;
+    }
+
+    public static void setInspector(Inspector inspector) {
+        InspectorApplication.inspector = inspector;
+        //Save object to Shared Preferences to prevent NPE when app resuming and android garbage collector has cleared this
+        SharedPrefs.setInspectorToPrefs(inspector);
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/MainActivity.java b/Main/src/gr/grnet/academicid/inspector/MainActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..445fef631dd1b0e35153e0bdfc70fe2dc421d07c
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/MainActivity.java
@@ -0,0 +1,125 @@
+package gr.grnet.academicid.inspector;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.Toast;
+import gr.grnet.academicid.inspector.domain.Inspector;
+import gr.grnet.academicid.inspector.parser.LoadUserResponse;
+import gr.grnet.academicid.inspector.services.ServiceHandler;
+import gr.grnet.academicid.inspector.parser.JSONParser;
+import gr.grnet.academicid.inspector.utilities.Constants;
+import gr.grnet.academicid.inspector.utilities.Tools;
+
+public class MainActivity extends Activity {
+
+    private EditText etxtUsername;
+    private EditText etxtPassword;
+
+    private ProgressDialog progressDialog;
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+
+        etxtUsername = (EditText) findViewById(R.id.etxt_username);
+        etxtPassword = (EditText) findViewById(R.id.etxt_password);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if (!Tools.isNetworkAvailable()) {
+            AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
+            alertDialog.setTitle(getString(R.string.title_no_net_available));
+            alertDialog.setMessage(getString(R.string.msg_no_net_available));
+
+            alertDialog.setPositiveButton(getString(R.string.action_next), new DialogInterface.OnClickListener() {
+                public void onClick(DialogInterface dialog, int which) {
+                    startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
+                }
+            });
+            alertDialog.setNegativeButton(getString(R.string.action_close), new DialogInterface.OnClickListener() {
+                public void onClick(DialogInterface dialog, int which) {
+                    finish();
+                }
+            });
+            alertDialog.show();
+        }
+    }
+
+    // Method called after 'Sign In' button is pressed
+    public void signIn(View view) {
+        // After 'Sign In' button is pressed, hide soft keyboard
+        InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+        if (getCurrentFocus() != null)
+            inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+
+        String username = etxtUsername.getText().toString();
+        String password = etxtPassword.getText().toString();
+
+        // Password is hashed and passed to async task for authorization
+        new Authenticate().execute(username, Tools.getHash(password));
+    }
+
+    // Inner class to perform the network connection asynchronously
+    private class Authenticate extends AsyncTask<String, Void, String> {
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+            // Showing progress dialog
+            progressDialog = new ProgressDialog(MainActivity.this);
+            progressDialog.setMessage(getString(R.string.msg_wait));
+            progressDialog.setCancelable(false);
+            progressDialog.show();
+        }
+
+        @Override
+        protected String doInBackground(String... credentials) {
+            return ServiceHandler.makeSingInCall(credentials[0], credentials[1]);
+        }
+
+        @Override
+        protected void onPostExecute(String result) {
+            super.onPostExecute(result);
+            // Dismiss the progress dialog
+            if (progressDialog.isShowing())
+                progressDialog.dismiss();
+
+            LoadUserResponse loadUserResponse = JSONParser.getResultOfLoadUser(result);
+
+            if (!loadUserResponse.isSuccessful()) {
+                Toast.makeText(getApplicationContext(), getString(R.string.msg_incorrect_credentials), Toast.LENGTH_SHORT).show();
+                Log.e(Constants.LOGTAG, "MainActivity.Authenticate.OnPostExecute(): Web service returned unsuccessfully with errorCode: " + loadUserResponse.getError());
+            } else {
+                Inspector inspector = loadUserResponse.getInspector();
+                String password = etxtPassword.getText().toString();
+                inspector.setPasswordHash(Tools.getHash(password));
+                InspectorApplication.setInspector(inspector);
+
+                Log.i(Constants.LOGTAG, "User: " + inspector.getUsername() + "successfully logged in");
+
+                // Check if user should change his password and redirect him to that view
+                if (inspector.shouldChangePswAtLogin()) {
+                    startActivity(new Intent(MainActivity.this, ChangePassword.class));
+                } else {
+                    startActivity(new Intent(MainActivity.this, InspectionResults.class));
+                }
+            }
+        }
+    }
+}
diff --git a/Main/src/gr/grnet/academicid/inspector/Preferences.java b/Main/src/gr/grnet/academicid/inspector/Preferences.java
new file mode 100644
index 0000000000000000000000000000000000000000..230b15aaf7573e25341edce0096ecde51ac87d27
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/Preferences.java
@@ -0,0 +1,11 @@
+package gr.grnet.academicid.inspector;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class Preferences extends PreferenceActivity {
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        addPreferencesFromResource(R.xml.preferences);
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/ScanQR.java b/Main/src/gr/grnet/academicid/inspector/ScanQR.java
new file mode 100644
index 0000000000000000000000000000000000000000..3fbbd45b698fc77fd1572319d60faf1e3d52a8bc
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/ScanQR.java
@@ -0,0 +1,60 @@
+package gr.grnet.academicid.inspector;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.widget.Toast;
+import com.dm.zbar.android.scanner.ZBarConstants;
+import com.dm.zbar.android.scanner.ZBarScannerActivity;
+import gr.grnet.academicid.inspector.utilities.Constants;
+import gr.grnet.academicid.inspector.utilities.Tools;
+import net.sourceforge.zbar.Symbol;
+
+public class ScanQR extends Activity {
+
+    private static final int ZBAR_SCANNER_REQUEST = 0;
+    private static final int ZBAR_QR_SCANNER_REQUEST = 1;
+
+    public static final String SCAN_RESULT = "ScanResult";
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        if (Tools.isCameraAvailable()) {
+            Intent intent = new Intent(this, ZBarScannerActivity.class);
+            intent.putExtra(ZBarConstants.SCAN_MODES, new int[]{Symbol.QRCODE});
+            startActivityForResult(intent, ZBAR_SCANNER_REQUEST);
+        } else {
+            Toast.makeText(this, getString(R.string.msg_no_camera_available), Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case ZBAR_SCANNER_REQUEST:
+            case ZBAR_QR_SCANNER_REQUEST:
+                if (resultCode == RESULT_OK) {
+                    String scanResult = data.getStringExtra(ZBarConstants.SCAN_RESULT);
+
+                    Intent intent = new Intent();
+                    intent.putExtra(SCAN_RESULT, scanResult);
+
+                    setResult(Activity.RESULT_OK, intent);
+                    finish();
+                } else if (resultCode == RESULT_CANCELED && data != null) {
+                    String error = data.getStringExtra(ZBarConstants.ERROR_INFO);
+                    if (!TextUtils.isEmpty(error)) {
+                        Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
+                        Log.e(Constants.LOGTAG, "ScanQR.onActivityResult(): " + error);
+                    }
+                }
+                break;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/domain/AcademicId.java b/Main/src/gr/grnet/academicid/inspector/domain/AcademicId.java
new file mode 100644
index 0000000000000000000000000000000000000000..bbc95c37fdf1489468e06fd05a8e92b1c23af979
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/domain/AcademicId.java
@@ -0,0 +1,114 @@
+package gr.grnet.academicid.inspector.domain;
+
+
+@SuppressWarnings("UnusedDeclaration")
+public class AcademicId {
+
+    private long serialNumber;
+    private String greekFirstname;
+    private String greekLastname;
+    private String latinFirstname;
+    private String latinLastname;
+    private String universityLocation;
+    private String residenceLocation;
+    private String pasoValidity;
+    private boolean webSuccess;
+    private String validationError;
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    public AcademicId() {
+    }
+
+    public long getSerialNumber() {
+        return serialNumber;
+    }
+
+    public void setSerialNumber(long serialNumber) {
+        this.serialNumber = serialNumber;
+    }
+
+    public String getGreekFirstname() {
+        return greekFirstname;
+    }
+
+    public void setGreekFirstname(String greekFirstname) {
+        this.greekFirstname = greekFirstname;
+    }
+
+    public String getGreekLastname() {
+        return greekLastname;
+    }
+
+    public void setGreekLastname(String greekLastname) {
+        this.greekLastname = greekLastname;
+    }
+
+    public String getLatinFirstname() {
+        return latinFirstname;
+    }
+
+    public void setLatinFirstname(String latinFirstname) {
+        this.latinFirstname = latinFirstname;
+    }
+
+    public String getLatinLastname() {
+        return latinLastname;
+    }
+
+    public void setLatinLastname(String latinLastname) {
+        this.latinLastname = latinLastname;
+    }
+
+    public String getUniversityLocation() {
+        return universityLocation;
+    }
+
+    public void setUniversityLocation(String universityLocation) {
+        this.universityLocation = universityLocation;
+    }
+
+    public String getResidenceLocation() {
+        return residenceLocation;
+    }
+
+    public void setResidenceLocation(String residenceLocation) {
+        this.residenceLocation = residenceLocation;
+    }
+
+    public String getPasoValidity() {
+        return pasoValidity;
+    }
+
+    public void setPasoValidity(String pasoValidity) {
+        this.pasoValidity = pasoValidity;
+    }
+
+    public boolean isWebSuccess() {
+        return webSuccess;
+    }
+
+    public void setWebSuccess(boolean webSuccess) {
+        this.webSuccess = webSuccess;
+    }
+
+    public String getValidationError() {
+        return validationError;
+    }
+
+    public void setValidationError(String validationError) {
+        this.validationError = validationError;
+    }
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    public Boolean isPasoValid() {
+        if (this.getPasoValidity().equals("Ναι")) return true;
+        if (this.getPasoValidity().equals("Όχι")) return false;
+        return null;
+    }
+
+    public boolean thereIsValidationError() {
+        return ((validationError != null) && (!validationError.equals("")) && (!validationError.equals("null")));
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/domain/Inspector.java b/Main/src/gr/grnet/academicid/inspector/domain/Inspector.java
new file mode 100644
index 0000000000000000000000000000000000000000..d06a334b4e7e84618a287a609ddb66a41301bde8
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/domain/Inspector.java
@@ -0,0 +1,91 @@
+package gr.grnet.academicid.inspector.domain;
+
+public class Inspector {
+
+    public static final String FIRSTNAME = "firstname";
+    public static final String LASTNAME = "lastname";
+    public static final String USERNAME = "username";
+    public static final String PASSWORD_HASH = "passwordHash";
+    public static final String CHANGE_PSW_AT_LOGIN = "changePassword";
+    public static final String ORG_ID = "orgId";
+    public static final String ORG_NAME = "orgName";
+    public static final String ORG_DESCRIPTION = "orgDescription";
+
+    private String firstname;
+    private String lastname;
+    private String username;
+    private String passwordHash;
+    private boolean changePswAtLogin;
+    private Long orgId;
+    private String orgName;
+    private String orgDescription;
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    public Inspector() {
+    }
+
+    public String getFirstname() {
+        return firstname;
+    }
+
+    public void setFirstname(String firstname) {
+        this.firstname = firstname;
+    }
+
+    public String getLastname() {
+        return lastname;
+    }
+
+    public void setLastname(String lastname) {
+        this.lastname = lastname;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPasswordHash() {
+        return passwordHash;
+    }
+
+    public void setPasswordHash(String passwordHash) {
+        this.passwordHash = passwordHash;
+    }
+
+    public boolean shouldChangePswAtLogin() {
+        return changePswAtLogin;
+    }
+
+    public void setChangePswAtLogin(boolean changePswAtLogin) {
+        this.changePswAtLogin = changePswAtLogin;
+    }
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
+
+    public String getOrgName() {
+        return orgName;
+    }
+
+    public void setOrgName(String orgName) {
+        this.orgName = orgName;
+    }
+
+    public String getOrgDescription() {
+        return orgDescription;
+    }
+
+    public void setOrgDescription(String orgDescription) {
+        this.orgDescription = orgDescription;
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/parser/ChangePasswordResponse.java b/Main/src/gr/grnet/academicid/inspector/parser/ChangePasswordResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..ae177f0f88866a6ff462babf8f94603236d9dc67
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/parser/ChangePasswordResponse.java
@@ -0,0 +1,35 @@
+package gr.grnet.academicid.inspector.parser;
+
+@SuppressWarnings("UnusedDeclaration")
+public class ChangePasswordResponse {
+
+    private String response;
+    private String error;
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    public ChangePasswordResponse(String response, String error) {
+        this.response = response;
+        this.error = error;
+    }
+
+    public String getResponse() {
+        return response;
+    }
+
+    public void setResponse(String response) {
+        this.response = response;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    public boolean isSuccessful() {
+        return (response.equals(JSONParser.RESPONSE_SUCCESSFUL));
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/parser/InspectAcademicIdResponse.java b/Main/src/gr/grnet/academicid/inspector/parser/InspectAcademicIdResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..d01ef658185689e490440f7b88810216c2ae75a5
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/parser/InspectAcademicIdResponse.java
@@ -0,0 +1,47 @@
+package gr.grnet.academicid.inspector.parser;
+
+import gr.grnet.academicid.inspector.domain.AcademicId;
+
+@SuppressWarnings("UnusedDeclaration")
+public class InspectAcademicIdResponse {
+
+    private String response;
+    private String error;
+    private AcademicId academicId;
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    public InspectAcademicIdResponse(String response, String error, AcademicId academicId) {
+        this.response = response;
+        this.error = error;
+        this.academicId = academicId;
+    }
+
+    public String getResponse() {
+        return response;
+    }
+
+    public void setResponse(String response) {
+        this.response = response;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    public AcademicId getAcademicId() {
+        return academicId;
+    }
+
+    public void setAcademicId(AcademicId academicId) {
+        this.academicId = academicId;
+    }
+
+    public boolean isSuccessful() {
+        return (response.equals(JSONParser.RESPONSE_SUCCESSFUL));
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/parser/JSONParser.java b/Main/src/gr/grnet/academicid/inspector/parser/JSONParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..48b0185ea17b9c5d660b2a5d0a4e5a59dcb4f86e
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/parser/JSONParser.java
@@ -0,0 +1,123 @@
+package gr.grnet.academicid.inspector.parser;
+
+import android.util.Log;
+import gr.grnet.academicid.inspector.domain.*;
+import gr.grnet.academicid.inspector.utilities.Constants;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class JSONParser {
+
+    // JSON Tags
+    private static final String TAG_RESPONSE = "response";
+    private static final String TAG_RESPONSE_ERROR = "errorReason";
+
+    public static final String RESPONSE_SUCCESSFUL = "SUCCESS";
+    public static final String RESPONSE_FAILED = "FAILURE";
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    /**
+     * Prevents this class from being instantiated.
+     */
+    private JSONParser() {
+    }
+
+    /**
+     * This method parses a json string and creates a {@link gr.grnet.academicid.inspector.parser.LoadUserResponse} object.
+     * It is called after {@link gr.grnet.academicid.inspector.services.ServiceHandler#makeSingInCall(String, String)}
+     *
+     * @param jsonString The string that should be parsed.
+     * @return A {@link gr.grnet.academicid.inspector.parser.LoadUserResponse} object.
+     */
+    public static LoadUserResponse getResultOfLoadUser(String jsonString) {
+        try {
+            JSONObject jsonObject = new JSONObject(jsonString);
+            String response = jsonObject.getString(TAG_RESPONSE);
+
+            if (response.equals(RESPONSE_SUCCESSFUL)) {
+                Inspector inspector = new Inspector();
+
+                JSONObject user = jsonObject.getJSONObject("user");
+                inspector.setFirstname(user.getString("firstName"));
+                inspector.setLastname(user.getString("lastName"));
+                inspector.setUsername(user.getString("username"));
+                inspector.setChangePswAtLogin(user.getBoolean("changePassword"));
+
+                JSONObject organization = user.getJSONObject("organization");
+                inspector.setOrgId(organization.getLong("id"));
+                inspector.setOrgName(organization.getString("name"));
+                inspector.setOrgDescription(organization.getString("description"));
+
+                return new LoadUserResponse(RESPONSE_SUCCESSFUL, null, inspector);
+            } else {
+                String error = jsonObject.getString(TAG_RESPONSE_ERROR);
+                return new LoadUserResponse(RESPONSE_FAILED, error, null);
+            }
+        } catch (JSONException e) {
+            Log.e(Constants.LOGTAG, "JSONParser.getResultOfLoadUser(): Error while parsing string: " + jsonString);
+            return null;
+        }
+    }
+
+    /**
+     * This method parses a json string and creates a {@link gr.grnet.academicid.inspector.parser.LoadUserResponse} object.
+     * It is called after {@link gr.grnet.academicid.inspector.services.ServiceHandler#makeInspectAcademicIdCall(String, String, String)}
+     *
+     * @param jsonString The string that should be parsed.
+     * @return A {@link gr.grnet.academicid.inspector.parser.InspectAcademicIdResponse} object.
+     */
+    public static InspectAcademicIdResponse getResultOfInspectAcademicId(String jsonString) {
+        try {
+            JSONObject jsonObject = new JSONObject(jsonString);
+            String response = jsonObject.getString(TAG_RESPONSE);
+
+            if (response.equals(RESPONSE_SUCCESSFUL)) {
+                AcademicId academicId = new AcademicId();
+
+                JSONObject inspectionResult = jsonObject.getJSONObject("inspectionResult");
+                academicId.setSerialNumber(inspectionResult.getLong("academicId"));
+                academicId.setGreekFirstname(inspectionResult.getString("greekFirstName"));
+                academicId.setGreekLastname(inspectionResult.getString("greekLastName"));
+                academicId.setLatinFirstname(inspectionResult.getString("latinFirstName"));
+                academicId.setLatinLastname(inspectionResult.getString("latinLastName"));
+                academicId.setUniversityLocation(inspectionResult.getString("universityLocation"));
+                academicId.setResidenceLocation(inspectionResult.getString("residenceLocation"));
+                academicId.setPasoValidity(inspectionResult.getString("pasoValidity"));
+                academicId.setWebSuccess(inspectionResult.getBoolean("webServiceSuccess"));
+                academicId.setValidationError(inspectionResult.getString("validationError"));
+
+                return new InspectAcademicIdResponse(RESPONSE_SUCCESSFUL, null, academicId);
+            } else {
+                String error = jsonObject.getString(TAG_RESPONSE_ERROR);
+                return new InspectAcademicIdResponse(RESPONSE_FAILED, error, null);
+            }
+        } catch (JSONException e) {
+            Log.e(Constants.LOGTAG, "JSONParser.getResultOfInspectAcademicId(): Error while parsing string: " + jsonString);
+            return null;
+        }
+    }
+
+    /**
+     * This method parses a json string and creates a {@link gr.grnet.academicid.inspector.parser.ChangePasswordResponse} object.
+     *
+     * @param jsonString The string that should be parsed.
+     * @return A {@link gr.grnet.academicid.inspector.parser.ChangePasswordResponse} object.
+     */
+    public static ChangePasswordResponse getResultOfUpdatePassword(String jsonString) {
+        try {
+            JSONObject jsonObject = new JSONObject(jsonString);
+            String response = jsonObject.getString(TAG_RESPONSE);
+
+            if (response.equals(RESPONSE_SUCCESSFUL)) {
+                return new ChangePasswordResponse(RESPONSE_SUCCESSFUL, null);
+            } else {
+                String error = jsonObject.getString(TAG_RESPONSE_ERROR);
+                return new ChangePasswordResponse(RESPONSE_FAILED, error);
+            }
+        } catch (JSONException e) {
+            Log.e(Constants.LOGTAG, "JSONParser.getResultOfUpdatePassword(): Error while parsing string: " + jsonString);
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/parser/LoadUserResponse.java b/Main/src/gr/grnet/academicid/inspector/parser/LoadUserResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..cdd61dedd9c9ae6868d90a0246924b63fa6d77b2
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/parser/LoadUserResponse.java
@@ -0,0 +1,47 @@
+package gr.grnet.academicid.inspector.parser;
+
+import gr.grnet.academicid.inspector.domain.Inspector;
+
+@SuppressWarnings("UnusedDeclaration")
+public class LoadUserResponse {
+
+    private String response;
+    private String error;
+    private Inspector inspector;
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    public LoadUserResponse(String response, String error, Inspector inspector) {
+        this.response = response;
+        this.error = error;
+        this.inspector = inspector;
+    }
+
+    public String getResponse() {
+        return response;
+    }
+
+    public void setResponse(String response) {
+        this.response = response;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    public Inspector getInspector() {
+        return inspector;
+    }
+
+    public void setInspector(Inspector inspector) {
+        this.inspector = inspector;
+    }
+
+    public boolean isSuccessful() {
+        return (response.equals(JSONParser.RESPONSE_SUCCESSFUL));
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/services/ServiceHandler.java b/Main/src/gr/grnet/academicid/inspector/services/ServiceHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..67eb0712668f30023732d3c500542bf4ad505467
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/services/ServiceHandler.java
@@ -0,0 +1,143 @@
+package gr.grnet.academicid.inspector.services;
+
+import android.util.Log;
+import gr.grnet.academicid.inspector.utilities.Constants;
+import gr.grnet.academicid.inspector.utilities.Tools;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+
+public class ServiceHandler {
+
+    // The URL of the server that handles the requests
+    private static final String URL = "http://academicidapp.grnet.gr:8080/";
+//    private static final String URL = "http://academicidappbuilder.grnet.gr:8080/";
+
+    // Path of web services
+    private static final String PATH = "admin/web/ws/users/";
+
+    // Each string represents a different call to a web service
+    private static final String LOAD_USER = "loadUser"; // Get method
+    private static final String INSPECT_ID = "inspectAcademicID"; // Post method
+    private static final String CHANGE_PSW = "updatePassword"; // Post method
+
+    // This is the content type dictated by server side
+    private static final String DEFAULT_CONTENT_TYPE = "application/json";
+
+    // This is the accepted encoding dictated by server side
+    private static final String ACCEPTED_ENCODING = "application/json";
+
+//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+
+    /**
+     * Prevents this class from being instantiated.
+     */
+    private ServiceHandler() {
+    }
+
+    /**
+     * This method verifies that a user is a valid user.
+     *
+     * @param username     The username of the user.
+     * @param passwordHash The password of the user hashed by {@link Tools#getHash(String)}.
+     * @return A json string.
+     */
+    public static String makeSingInCall(String username, String passwordHash) {
+        try {
+            HttpGet httpMethod = new HttpGet(URL + PATH + LOAD_USER);
+            httpMethod.addHeader("Content-Type", DEFAULT_CONTENT_TYPE);
+            httpMethod.addHeader("Accept-Encoding", ACCEPTED_ENCODING);
+
+            String credentialsEncoded = Tools.encodeBase64(username, passwordHash);
+            httpMethod.addHeader("Authorization", "Basic " + credentialsEncoded);
+
+            DefaultHttpClient client = new DefaultHttpClient();
+            HttpResponse httpResponse = client.execute(httpMethod);
+            HttpEntity httpEntity = httpResponse.getEntity();
+
+            return EntityUtils.toString(httpEntity);
+        } catch (IOException e) {
+            Log.e(Constants.LOGTAG, "ServiceHandler.makeSignInCall(): Error while user: " + username + " trying to sign in ", e);
+            return null;
+        }
+    }
+
+    /**
+     * This method checks the validity of an AcademicID as a reduced price voucher (PASO).
+     *
+     * @param username     The username of the user performing the check.
+     * @param passwordHash The password (hashed) of the user performing the request.
+     * @param academicId   The AcademicID serial number that is checked.
+     * @return A json string.
+     */
+    public static String makeInspectAcademicIdCall(String username, String passwordHash, String academicId) {
+        try {
+            HttpPost httpMethod = new HttpPost(URL + PATH + INSPECT_ID);
+            httpMethod.addHeader("Content-Type", DEFAULT_CONTENT_TYPE);
+            httpMethod.addHeader("Accept-Encoding", ACCEPTED_ENCODING);
+
+            String credentialsEncoded = Tools.encodeBase64(username, passwordHash);
+            httpMethod.addHeader("Authorization", "Basic " + credentialsEncoded);
+
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("SubmissionCode", academicId);
+            httpMethod.setEntity(new StringEntity(jsonObject.toString()));
+
+            DefaultHttpClient client = new DefaultHttpClient();
+            HttpResponse httpResponse = client.execute(httpMethod);
+            HttpEntity httpEntity = httpResponse.getEntity();
+
+            return EntityUtils.toString(httpEntity);
+        } catch (JSONException e) {
+            Log.e(Constants.LOGTAG, "ServiceHandler.makeInspectAcademicIdCall(): Error while trying to construct JSON Offer", e);
+            return null;
+        } catch (IOException e) {
+            Log.e(Constants.LOGTAG, "ServiceHandler.makeInspectAcademicIdCall(): Error while user " + username + " trying to validate AcademicID: " + academicId, e);
+            return null;
+        }
+    }
+
+    /**
+     * This method performs a password change request.
+     *
+     * @param username        The username of the user.
+     * @param passwordHash    The password of the user hashed by {@link Tools#getHash(String)}.
+     * @param newPasswordHash The new password of the user hashed by {@link Tools#getHash(String)}.
+     * @return A json string.
+     */
+    public static String makeChangePswCall(String username, String passwordHash, String newPasswordHash) {
+        try {
+            HttpPost httpMethod = new HttpPost(URL + PATH + CHANGE_PSW);
+            httpMethod.addHeader("Content-Type", DEFAULT_CONTENT_TYPE);
+            httpMethod.addHeader("Accept-Encoding", ACCEPTED_ENCODING);
+
+            String credentialsEncoded = Tools.encodeBase64(username, passwordHash);
+            httpMethod.addHeader("Authorization", "Basic " + credentialsEncoded);
+
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("newPassword", newPasswordHash);
+
+            httpMethod.setEntity(new StringEntity(jsonObject.toString()));
+
+            DefaultHttpClient client = new DefaultHttpClient();
+            HttpResponse httpResponse = client.execute(httpMethod);
+            HttpEntity httpEntity = httpResponse.getEntity();
+
+            return EntityUtils.toString(httpEntity);
+        } catch (JSONException e) {
+            Log.e(Constants.LOGTAG, "ServiceHandler.makeChangePswCall(): Error while trying to construct JSON string", e);
+            return null;
+        } catch (IOException e) {
+            Log.e(Constants.LOGTAG, "ServiceHandler.makeChangePswCall(): Error while user: " + username + " trying to change password", e);
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/utilities/Constants.java b/Main/src/gr/grnet/academicid/inspector/utilities/Constants.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d984e78b100961ac378c91165fc860784882f8e
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/utilities/Constants.java
@@ -0,0 +1,24 @@
+package gr.grnet.academicid.inspector.utilities;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Constants globally available in Inspector application.
+ */
+public class Constants {
+
+    public static final String LOGTAG = "Inspector";
+
+    // The message digest algorithm that is used to hash user password.
+    public static final String DIGEST_ALGORITHM = "MD5";
+
+    // An academicId is invalid if:
+    // (response=success && pasovalidity==false) OR (response=success && webservicesuccess==false && validationerror ΙΝ ValidationErrorList
+    public static List<String> ValidationErrorList = Arrays.asList(
+            "Δεν βρέθηκε αίτηση με το 12ψήφιο κωδικό που εισάγατε",
+            "Ο 12ψήφιος που εισάγατε δεν αντιστοιχεί σε αίτηση φοιτητή",
+            "Η Ακαδημαϊκή Ταυτότητα δεν έχει υποβληθεί οριστικά από το φοιτητή",
+            "Η Ακαδημαϊκή Ταυτότητα έχει απορριφθεί από τη γραμματεία"
+    );
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/utilities/SharedPrefs.java b/Main/src/gr/grnet/academicid/inspector/utilities/SharedPrefs.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed02da47f5a195ae579d1085d77b357fec4727b8
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/utilities/SharedPrefs.java
@@ -0,0 +1,79 @@
+package gr.grnet.academicid.inspector.utilities;
+
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import gr.grnet.academicid.inspector.InspectorApplication;
+import gr.grnet.academicid.inspector.domain.Inspector;
+
+/**
+ * Helper class for handling Preferences.
+ */
+public class SharedPrefs {
+
+    /**
+     * Prevents this class from being instantiated.
+     */
+    private SharedPrefs() {
+    }
+
+    /**
+     * This method retrieves an Inspector object from Shared Preferences.
+     *
+     * @return An Inspector object.
+     */
+    public static Inspector getInspectorFromPrefs() {
+        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(InspectorApplication.getAppContext());
+
+        Inspector inspector = new Inspector();
+        inspector.setFirstname(preferences.getString(Inspector.FIRSTNAME, ""));
+        inspector.setLastname(preferences.getString(Inspector.LASTNAME, ""));
+        inspector.setUsername(preferences.getString(Inspector.USERNAME, ""));
+        inspector.setPasswordHash(preferences.getString(Inspector.PASSWORD_HASH, ""));
+        inspector.setChangePswAtLogin(preferences.getBoolean(Inspector.CHANGE_PSW_AT_LOGIN, false));
+        inspector.setOrgId(preferences.getLong(Inspector.ORG_ID, 0));
+        inspector.setOrgName(preferences.getString(Inspector.ORG_NAME, ""));
+        inspector.setOrgDescription(preferences.getString(Inspector.ORG_DESCRIPTION, ""));
+
+        return inspector;
+    }
+
+    /**
+     * This method stores Inspector object in Shared Preferences.
+     *
+     * @param inspector The Inspector object that will be saved in Shared Preferences.
+     */
+    public static void setInspectorToPrefs(Inspector inspector) {
+        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(InspectorApplication.getAppContext());
+        SharedPreferences.Editor preferencesEditor = preferences.edit();
+
+        preferencesEditor.putString(Inspector.FIRSTNAME, inspector.getFirstname());
+        preferencesEditor.putString(Inspector.LASTNAME, inspector.getLastname());
+        preferencesEditor.putString(Inspector.USERNAME, inspector.getUsername());
+        preferencesEditor.putString(Inspector.PASSWORD_HASH, inspector.getPasswordHash());
+        preferencesEditor.putBoolean(Inspector.CHANGE_PSW_AT_LOGIN, inspector.shouldChangePswAtLogin());
+        preferencesEditor.putLong(Inspector.ORG_ID, inspector.getOrgId());
+        preferencesEditor.putString(Inspector.ORG_NAME, inspector.getOrgName());
+        preferencesEditor.putString(Inspector.ORG_DESCRIPTION, inspector.getOrgDescription());
+
+        preferencesEditor.commit();
+    }
+
+    /**
+     * This method clear Inspector values from Shared Preferences.
+     */
+    public static void ClearInspectorFromPrefs() {
+        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(InspectorApplication.getAppContext());
+        SharedPreferences.Editor preferencesEditor = preferences.edit();
+
+        preferencesEditor.remove(Inspector.FIRSTNAME);
+        preferencesEditor.remove(Inspector.LASTNAME);
+        preferencesEditor.remove(Inspector.USERNAME);
+        preferencesEditor.remove(Inspector.PASSWORD_HASH);
+        preferencesEditor.remove(Inspector.CHANGE_PSW_AT_LOGIN);
+        preferencesEditor.remove(Inspector.ORG_ID);
+        preferencesEditor.remove(Inspector.ORG_NAME);
+        preferencesEditor.remove(Inspector.ORG_DESCRIPTION);
+
+        preferencesEditor.commit();
+    }
+}
\ No newline at end of file
diff --git a/Main/src/gr/grnet/academicid/inspector/utilities/Tools.java b/Main/src/gr/grnet/academicid/inspector/utilities/Tools.java
new file mode 100644
index 0000000000000000000000000000000000000000..959b1f0cd1bcb8cc0fa39377cbe7c82cb73da65d
--- /dev/null
+++ b/Main/src/gr/grnet/academicid/inspector/utilities/Tools.java
@@ -0,0 +1,117 @@
+package gr.grnet.academicid.inspector.utilities;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.util.Base64;
+import android.util.Log;
+import gr.grnet.academicid.inspector.InspectorApplication;
+import gr.grnet.academicid.inspector.domain.AcademicId;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Helper class with utility functionality.
+ */
+public class Tools {
+
+    /**
+     * Prevents this class from being instantiated.
+     */
+    private Tools() {
+    }
+
+    /**
+     * This method verifies that the device has network connectivity.
+     *
+     * @return True if the device has network connectivity.
+     */
+    public static boolean isNetworkAvailable() {
+        ConnectivityManager connectivityManager = (ConnectivityManager) InspectorApplication.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
+        return (activeNetworkInfo != null && activeNetworkInfo.isConnected());
+    }
+
+    /**
+     * This method verifies that a camera is available.
+     *
+     * @return True if the camera of the device is available.
+     */
+    public static boolean isCameraAvailable() {
+        PackageManager packageManager = InspectorApplication.getAppContext().getPackageManager();
+        return (packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA));
+    }
+
+    /**
+     * This method verifies that the passed parameter is numeric.
+     *
+     * @param numStr Contains the questioned value.
+     * @return True if numStr is numeric.
+     */
+    public static boolean isNumericValue(String numStr) {
+        try {
+            //noinspection ResultOfMethodCallIgnored
+            Long.parseLong(numStr);
+            return true;
+        } catch (NumberFormatException nfe) {
+            return false;
+        }
+    }
+
+    /**
+     * This method calculates the hash value of the parameter passed based on the DIGEST_ALGORITHM that is used.
+     *
+     * @param message The plain message that will be hashed
+     * @return The hash equivalent of message according to digest algorithm that was used.
+     */
+    public static String getHash(String message) {
+        try {
+            MessageDigest messageDigest = MessageDigest.getInstance(Constants.DIGEST_ALGORITHM);
+            byte[] hashedArray = messageDigest.digest(message.getBytes());
+            BigInteger hashedNumber = new BigInteger(1, hashedArray);
+
+            return hashedNumber.toString(16);
+        } catch (NoSuchAlgorithmException e) {
+            Log.e(Constants.LOGTAG, "Tools.getHash(): The designated algorithm: " + Constants.DIGEST_ALGORITHM + " can't be found.", e);
+            return null;
+        }
+    }
+
+    /**
+     * This method concatenates the two parameters passed and encodes them using Base64 scheme.
+     *
+     * @param str1 This first parameter that needs to be encoded.
+     * @param str2 This second parameter  that needs to be encoded.
+     * @return a encoded with Base64 scheme String.
+     */
+    public static String encodeBase64(String str1, String str2) {
+        byte[] authEncBytes = Base64.encode((str1 + ":" + str2).getBytes(), Base64.NO_WRAP);
+        return new String(authEncBytes);
+    }
+
+    /**
+     * This method constructs a 2+2 letter concatenated string from firstname and lastname.
+     * Method checks if greek name exists and if not proceeds with latin name.
+     *
+     * @param academicId the object containing the first and lastname that should be concatenated to 2+2 letters.
+     * @return a 2+2 concatenated string containing the first two letters from firstname and lastname.
+     */
+    public static String concatenateName(AcademicId academicId) {
+        if (academicId == null) {
+            return null;
+
+        } else if ((academicId.getGreekFirstname() != null) && (academicId.getGreekFirstname().length() != 0) &&
+                (academicId.getGreekLastname() != null) && (academicId.getGreekLastname().length() != 0)) {
+            return (academicId.getGreekFirstname().substring(0, 2) + " " + academicId.getGreekLastname().substring(0, 2));
+
+        } else if ((academicId.getLatinFirstname() != null) && (academicId.getLatinFirstname().length() != 0) &&
+                (academicId.getLatinLastname() != null) && (academicId.getLatinLastname().length() != 0))
+            return (academicId.getLatinFirstname().substring(0, 2) + " " + academicId.getLatinLastname().substring(0, 2));
+
+        else
+            return null;
+    }
+}
\ No newline at end of file
diff --git a/ZBarScannerLibrary/AndroidManifest.xml b/ZBarScannerLibrary/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5d5925b440dbec519e525d9f6dc5b4b784d8d4e0
--- /dev/null
+++ b/ZBarScannerLibrary/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.dm.zbar.android.scanner"
+      android:versionCode="1"
+      android:versionName="1.0">
+
+    <uses-permission android:name="android.permission.CAMERA"/>
+    <uses-feature android:name="android.hardware.camera" />
+    <uses-sdk android:minSdkVersion="8" />
+
+    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
+        <activity android:name="ZBarScannerActivity"
+                  android:screenOrientation="landscape"
+                  android:label="@string/app_name" />
+    </application>
+</manifest>
diff --git a/ZBarScannerLibrary/build.xml b/ZBarScannerLibrary/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b72a8d3ba15328b264f9c9e839e56beefa0bc2f0
--- /dev/null
+++ b/ZBarScannerLibrary/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="ZBarScanner" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- if sdk.dir was not set from one of the property file, then
+         get it from the ANDROID_HOME env var.
+         This must be done before we load project.properties since
+         the proguard config can use sdk.dir -->
+    <property environment="env" />
+    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+        <isset property="env.ANDROID_HOME" />
+    </condition>
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+            unless="sdk.dir"
+    />
+
+    <!--
+        Import per project custom build rules if present at the root of the project.
+        This is the place to put custom intermediary targets such as:
+            -pre-build
+            -pre-compile
+            -post-compile (This is typically used for code obfuscation.
+                           Compiled code location: ${out.classes.absolute.dir}
+                           If this is not done in place, override ${out.dex.input.absolute.dir})
+            -post-package
+            -post-build
+            -pre-clean
+    -->
+    <import file="custom_rules.xml" optional="true" />
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/ZBarScannerLibrary/gen/com/dm/zbar/android/scanner/BuildConfig.java b/ZBarScannerLibrary/gen/com/dm/zbar/android/scanner/BuildConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..5cdff0b68a4c51e48ed1a40f69c80ba8e4fbdbe3
--- /dev/null
+++ b/ZBarScannerLibrary/gen/com/dm/zbar/android/scanner/BuildConfig.java
@@ -0,0 +1,8 @@
+/*___Generated_by_IDEA___*/
+
+package com.dm.zbar.android.scanner;
+
+/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
+public final class BuildConfig {
+  public final static boolean DEBUG = Boolean.parseBoolean(null);
+}
\ No newline at end of file
diff --git a/ZBarScannerLibrary/gen/com/dm/zbar/android/scanner/Manifest.java b/ZBarScannerLibrary/gen/com/dm/zbar/android/scanner/Manifest.java
new file mode 100644
index 0000000000000000000000000000000000000000..54ea9b1c6ed0fedbcb8e78a83d2739c2f54dc274
--- /dev/null
+++ b/ZBarScannerLibrary/gen/com/dm/zbar/android/scanner/Manifest.java
@@ -0,0 +1,7 @@
+/*___Generated_by_IDEA___*/
+
+package com.dm.zbar.android.scanner;
+
+/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
+public final class Manifest {
+}
\ No newline at end of file
diff --git a/ZBarScannerLibrary/gen/com/dm/zbar/android/scanner/R.java b/ZBarScannerLibrary/gen/com/dm/zbar/android/scanner/R.java
new file mode 100644
index 0000000000000000000000000000000000000000..8eaeca3fa6ac8d1902648e387ffe2901d55ae6c1
--- /dev/null
+++ b/ZBarScannerLibrary/gen/com/dm/zbar/android/scanner/R.java
@@ -0,0 +1,7 @@
+/*___Generated_by_IDEA___*/
+
+package com.dm.zbar.android.scanner;
+
+/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
+public final class R {
+}
\ No newline at end of file
diff --git a/ZBarScannerLibrary/libs/armeabi-v7a/libiconv.so b/ZBarScannerLibrary/libs/armeabi-v7a/libiconv.so
new file mode 100644
index 0000000000000000000000000000000000000000..2bcbb70c3079cdd35455410d069a23f6c8d0832a
Binary files /dev/null and b/ZBarScannerLibrary/libs/armeabi-v7a/libiconv.so differ
diff --git a/ZBarScannerLibrary/libs/armeabi-v7a/libzbarjni.so b/ZBarScannerLibrary/libs/armeabi-v7a/libzbarjni.so
new file mode 100644
index 0000000000000000000000000000000000000000..2693dbb140b58528bc90aa03c2a98c898fdfed05
Binary files /dev/null and b/ZBarScannerLibrary/libs/armeabi-v7a/libzbarjni.so differ
diff --git a/ZBarScannerLibrary/libs/armeabi/libiconv.so b/ZBarScannerLibrary/libs/armeabi/libiconv.so
new file mode 100644
index 0000000000000000000000000000000000000000..9c7150de295ff7a7fded8f00fcdb275a8ec15bf7
Binary files /dev/null and b/ZBarScannerLibrary/libs/armeabi/libiconv.so differ
diff --git a/ZBarScannerLibrary/libs/armeabi/libzbarjni.so b/ZBarScannerLibrary/libs/armeabi/libzbarjni.so
new file mode 100644
index 0000000000000000000000000000000000000000..3d4a8ac3232507703b539320c6262ad0c8aacee7
Binary files /dev/null and b/ZBarScannerLibrary/libs/armeabi/libzbarjni.so differ
diff --git a/ZBarScannerLibrary/libs/x86/libiconv.so b/ZBarScannerLibrary/libs/x86/libiconv.so
new file mode 100644
index 0000000000000000000000000000000000000000..6ab43e51d4793851deb215cfe04dba85a733d759
Binary files /dev/null and b/ZBarScannerLibrary/libs/x86/libiconv.so differ
diff --git a/ZBarScannerLibrary/libs/x86/libzbarjni.so b/ZBarScannerLibrary/libs/x86/libzbarjni.so
new file mode 100644
index 0000000000000000000000000000000000000000..d64f517ad58295affd786686c83667b0b7d0dccb
Binary files /dev/null and b/ZBarScannerLibrary/libs/x86/libzbarjni.so differ
diff --git a/ZBarScannerLibrary/libs/zbar.jar b/ZBarScannerLibrary/libs/zbar.jar
new file mode 100644
index 0000000000000000000000000000000000000000..7d50b957809c65f37e5606988e9fc06410873029
Binary files /dev/null and b/ZBarScannerLibrary/libs/zbar.jar differ
diff --git a/ZBarScannerLibrary/project.properties b/ZBarScannerLibrary/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..dfa4dd0977fb676f5e209bda13e5a285ecff5c71
--- /dev/null
+++ b/ZBarScannerLibrary/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-16
+android.library=true
diff --git a/ZBarScannerLibrary/res/drawable-hdpi/ic_launcher.png b/ZBarScannerLibrary/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..96a442e5b8e9394ccf50bab9988cb2316026245d
Binary files /dev/null and b/ZBarScannerLibrary/res/drawable-hdpi/ic_launcher.png differ
diff --git a/ZBarScannerLibrary/res/drawable-ldpi/ic_launcher.png b/ZBarScannerLibrary/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..99238729d8753585237a65b91c7cde426c90baef
Binary files /dev/null and b/ZBarScannerLibrary/res/drawable-ldpi/ic_launcher.png differ
diff --git a/ZBarScannerLibrary/res/drawable-mdpi/ic_launcher.png b/ZBarScannerLibrary/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..359047dfa4ed206e41e2354f9c6b307e713efe32
Binary files /dev/null and b/ZBarScannerLibrary/res/drawable-mdpi/ic_launcher.png differ
diff --git a/ZBarScannerLibrary/res/drawable-xhdpi/ic_launcher.png b/ZBarScannerLibrary/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..71c6d760f05183ef8a47c614d8d13380c8528499
Binary files /dev/null and b/ZBarScannerLibrary/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/ZBarScannerLibrary/res/values/strings.xml b/ZBarScannerLibrary/res/values/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e73122b930392a0a22ba5640f0171e53ae913f98
--- /dev/null
+++ b/ZBarScannerLibrary/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">ZBar Scanner</string>
+</resources>
diff --git a/ZBarScannerLibrary/src/com/dm/zbar/android/scanner/CameraPreview.java b/ZBarScannerLibrary/src/com/dm/zbar/android/scanner/CameraPreview.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa08c5c9ba61ac5786ecde3ec128e9514d6066ba
--- /dev/null
+++ b/ZBarScannerLibrary/src/com/dm/zbar/android/scanner/CameraPreview.java
@@ -0,0 +1,188 @@
+package com.dm.zbar.android.scanner;
+
+import android.content.Context;
+import android.hardware.Camera;
+import android.hardware.Camera.AutoFocusCallback;
+import android.hardware.Camera.PreviewCallback;
+import android.hardware.Camera.Size;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.ViewGroup;
+import java.io.IOException;
+import java.util.List;
+
+class CameraPreview extends ViewGroup implements SurfaceHolder.Callback {
+    private final String TAG = "CameraPreview";
+
+    SurfaceView mSurfaceView;
+    SurfaceHolder mHolder;
+    Size mPreviewSize;
+    List<Size> mSupportedPreviewSizes;
+    Camera mCamera;
+    PreviewCallback mPreviewCallback;
+    AutoFocusCallback mAutoFocusCallback;
+
+    boolean portrait = false;
+
+    CameraPreview(Context context, PreviewCallback previewCallback, AutoFocusCallback autoFocusCb) {
+        super(context);
+
+        mPreviewCallback = previewCallback;
+        mAutoFocusCallback = autoFocusCb;
+        mSurfaceView = new SurfaceView(context);
+        addView(mSurfaceView);
+
+        // Install a SurfaceHolder.Callback so we get notified when the
+        // underlying surface is created and destroyed.
+        mHolder = mSurfaceView.getHolder();
+        mHolder.addCallback(this);
+        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+    }
+
+    public void setCamera(Camera camera) {
+        mCamera = camera;
+        if (mCamera != null) {
+            mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
+            requestLayout();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // We purposely disregard child measurements because act as a
+        // wrapper to a SurfaceView that centers the camera preview instead
+        // of stretching it.
+        final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
+        final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
+        setMeasuredDimension(width, height);
+
+        // Check if the device is in portrait mode
+        portrait = (height > width);
+
+        if (mSupportedPreviewSizes != null) {
+            if (portrait)
+                mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, height, width);
+            else
+                mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        if (changed && getChildCount() > 0) {
+            final View child = getChildAt(0);
+
+            final int width = r - l;
+            final int height = b - t;
+
+            int previewWidth = width;
+            int previewHeight = height;
+            if (mPreviewSize != null) {
+                if (portrait) {
+                    previewWidth = mPreviewSize.height;
+                    previewHeight = mPreviewSize.width;
+                } else {
+                    previewWidth = mPreviewSize.width;
+                    previewHeight = mPreviewSize.height;
+                }
+            }
+
+            // Center the child SurfaceView within the parent.
+            if (width * previewHeight > height * previewWidth) {
+                final int scaledChildWidth = previewWidth * height / previewHeight;
+                child.layout((width - scaledChildWidth) / 2, 0,
+                        (width + scaledChildWidth) / 2, height);
+            } else {
+                final int scaledChildHeight = previewHeight * width / previewWidth;
+                child.layout(0, (height - scaledChildHeight) / 2,
+                        width, (height + scaledChildHeight) / 2);
+            }
+        }
+    }
+
+    public void hideSurfaceView() {
+        mSurfaceView.setVisibility(View.INVISIBLE);
+    }
+
+    public void showSurfaceView() {
+        mSurfaceView.setVisibility(View.VISIBLE);
+    }
+
+    public void surfaceCreated(SurfaceHolder holder) {
+        // The Surface has been created, acquire the camera and tell it where
+        // to draw.
+        try {
+            if (mCamera != null) {
+                mCamera.setPreviewDisplay(holder);
+            }
+        } catch (IOException exception) {
+            Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
+        }
+    }
+
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        // Surface will be destroyed when we return, so stop the preview.
+        if (mCamera != null) {
+            mCamera.cancelAutoFocus();
+            mCamera.stopPreview();
+        }
+    }
+
+
+    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
+        final double ASPECT_TOLERANCE = 0.1;
+        double targetRatio = (double) w / h;
+        if (sizes == null) return null;
+
+        Size optimalSize = null;
+        double minDiff = Double.MAX_VALUE;
+
+        int targetHeight = h;
+
+        // Try to find an size match aspect ratio and size
+        for (Size size : sizes) {
+            double ratio = (double) size.width / size.height;
+            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
+            if (Math.abs(size.height - targetHeight) < minDiff) {
+                optimalSize = size;
+                minDiff = Math.abs(size.height - targetHeight);
+            }
+        }
+
+        // Cannot find the one match the aspect ratio, ignore the requirement
+        if (optimalSize == null) {
+            minDiff = Double.MAX_VALUE;
+            for (Size size : sizes) {
+                if (Math.abs(size.height - targetHeight) < minDiff) {
+                    optimalSize = size;
+                    minDiff = Math.abs(size.height - targetHeight);
+                }
+            }
+        }
+        return optimalSize;
+    }
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        if (holder.getSurface() == null) {
+            // preview surface does not exist
+            return;
+        }
+
+        if (mCamera != null) {
+            // Now that the size is known, set up the camera parameters and begin
+            // the preview.
+            Camera.Parameters parameters = mCamera.getParameters();
+            parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
+            requestLayout();
+
+            if (portrait) mCamera.setDisplayOrientation(90);
+            mCamera.setParameters(parameters);
+            mCamera.setPreviewCallback(mPreviewCallback);
+            mCamera.startPreview();
+            mCamera.autoFocus(mAutoFocusCallback);
+        }
+    }
+
+}
diff --git a/ZBarScannerLibrary/src/com/dm/zbar/android/scanner/ZBarConstants.java b/ZBarScannerLibrary/src/com/dm/zbar/android/scanner/ZBarConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..f96037f1b5053b90d20a6280ed3a3eb976559392
--- /dev/null
+++ b/ZBarScannerLibrary/src/com/dm/zbar/android/scanner/ZBarConstants.java
@@ -0,0 +1,8 @@
+package com.dm.zbar.android.scanner;
+
+public interface ZBarConstants {
+    public static final String SCAN_MODES = "SCAN_MODES";
+    public static final String SCAN_RESULT = "SCAN_RESULT";
+    public static final String SCAN_RESULT_TYPE = "SCAN_RESULT_TYPE";
+    public static final String ERROR_INFO = "ERROR_INFO";
+}
diff --git a/ZBarScannerLibrary/src/com/dm/zbar/android/scanner/ZBarScannerActivity.java b/ZBarScannerLibrary/src/com/dm/zbar/android/scanner/ZBarScannerActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d21992203dd062028a381b8566c4651c457d1fc
--- /dev/null
+++ b/ZBarScannerLibrary/src/com/dm/zbar/android/scanner/ZBarScannerActivity.java
@@ -0,0 +1,177 @@
+package com.dm.zbar.android.scanner;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.hardware.Camera;
+import android.os.Bundle;
+import android.os.Handler;
+import android.text.TextUtils;
+import gr.grnet.academicid.inspector.InspectionResults;
+import net.sourceforge.zbar.Config;
+import net.sourceforge.zbar.Image;
+import net.sourceforge.zbar.ImageScanner;
+import net.sourceforge.zbar.Symbol;
+import net.sourceforge.zbar.SymbolSet;
+
+public class ZBarScannerActivity extends Activity implements Camera.PreviewCallback, ZBarConstants {
+
+    private CameraPreview mPreview;
+    private Camera mCamera;
+    private ImageScanner mScanner;
+    private Handler mAutoFocusHandler;
+    private boolean mPreviewing = true;
+
+    static {
+        System.loadLibrary("iconv");
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        if (!isCameraAvailable()) {
+            // Cancel request if there is no rear-facing camera.
+            cancelRequest();
+            return;
+        }
+
+        // Hide the window title.
+//        requestWindowFeature(Window.FEATURE_NO_TITLE);
+//        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+
+        mAutoFocusHandler = new Handler();
+
+        // Create and configure the ImageScanner;
+        setupScanner();
+
+        // Create a RelativeLayout container that will hold a SurfaceView,
+        // and set it as the content of our activity.
+        mPreview = new CameraPreview(this, this, autoFocusCB);
+        setContentView(mPreview);
+    }
+
+    public void setupScanner() {
+        mScanner = new ImageScanner();
+        mScanner.setConfig(0, Config.X_DENSITY, 3);
+        mScanner.setConfig(0, Config.Y_DENSITY, 3);
+
+        int[] symbols = getIntent().getIntArrayExtra(SCAN_MODES);
+        if (symbols != null) {
+            mScanner.setConfig(Symbol.NONE, Config.ENABLE, 0);
+            for (int symbol : symbols) {
+                mScanner.setConfig(symbol, Config.ENABLE, 1);
+            }
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // Open the default i.e. the first rear facing camera.
+        mCamera = Camera.open();
+        if (mCamera == null) {
+            // Cancel request if mCamera is null.
+            cancelRequest();
+            return;
+        }
+
+        mPreview.setCamera(mCamera);
+        mPreview.showSurfaceView();
+
+        mPreviewing = true;
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        // Because the Camera object is a shared resource, it's very
+        // important to release it when the activity is paused.
+        if (mCamera != null) {
+            mPreview.setCamera(null);
+            mCamera.cancelAutoFocus();
+            mCamera.setPreviewCallback(null);
+            mCamera.stopPreview();
+            mCamera.release();
+
+            // According to Jason Kuang on http://stackoverflow.com/questions/6519120/how-to-recover-camera-preview-from-sleep,
+            // there might be surface recreation problems when the device goes to sleep. So lets just hide it and
+            // recreate on resume
+            mPreview.hideSurfaceView();
+
+            mPreviewing = false;
+            mCamera = null;
+        }
+    }
+
+    public boolean isCameraAvailable() {
+        PackageManager pm = getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
+    }
+
+    public void cancelRequest() {
+        Intent dataIntent = new Intent();
+        dataIntent.putExtra(ERROR_INFO, "Camera unavailable");
+        setResult(Activity.RESULT_CANCELED, dataIntent);
+        finish();
+    }
+
+    public void onPreviewFrame(byte[] data, Camera camera) {
+        Camera.Parameters parameters = camera.getParameters();
+        Camera.Size size = parameters.getPreviewSize();
+
+        Image barcode = new Image(size.width, size.height, "Y800");
+        barcode.setData(data);
+
+        int result = mScanner.scanImage(barcode);
+
+        if (result != 0) {
+            mCamera.cancelAutoFocus();
+            mCamera.setPreviewCallback(null);
+            mCamera.stopPreview();
+            mPreviewing = false;
+            SymbolSet syms = mScanner.getResults();
+            for (Symbol sym : syms) {
+                String symData = sym.getData();
+                if (!TextUtils.isEmpty(symData)) {
+                    Intent dataIntent = new Intent();
+                    dataIntent.putExtra(SCAN_RESULT, symData);
+                    dataIntent.putExtra(SCAN_RESULT_TYPE, sym.getType());
+                    setResult(Activity.RESULT_OK, dataIntent);
+                    finish();
+                    break;
+                }
+            }
+        }
+    }
+
+    private Runnable doAutoFocus = new Runnable() {
+        public void run() {
+            if (mCamera != null && mPreviewing) {
+                mCamera.autoFocus(autoFocusCB);
+            }
+        }
+    };
+
+    // Mimic continuous auto-focusing
+    Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
+        public void onAutoFocus(boolean success, Camera camera) {
+            mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
+        }
+    };
+
+    @Override
+    public void onBackPressed() {
+        super.onPause();
+        // Starting InspectionResults activity
+        Intent intent = new Intent(this, InspectionResults.class);
+
+        // Pop the existing activity instead of creating a new one
+        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+        startActivity(intent);
+    }
+}
+