diff --git a/.gitignore b/.gitignore
index 73ebd01968826de5bb4291d1bcd9d54c64e1d6e8..560276d02d4a8d66d92a8cbdfae9b049dc7314b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,3 +17,5 @@
 .env
 docker-compose.yaml
 .editorconfig
+package-lock.json
+*~
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index fdf4292066895a8eb033a0321249efb3e7869930..610933e85ae52dcb4a6c1a89fc063043fd2d0ec7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -24,23 +24,30 @@ stages:
 
 run_test:
     stage: test
-    before_script:
-      - apt-get update -q -y
-      - apt-get install wget gnupg -y
-      - echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main" > /etc/apt/sources.list.d/pgdg.list
-      - wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
-      - apt-get update -q -y
-      - apt-get install -y postgresql-client-10
-      - git clone --recurse-submodules https://gitlab.c3sl.ufpr.br/simmctic/form-creator/form-creator-database.git form-creator-database
-      - cd  form-creator-database
-      - psql-manager/manager.sh create workspace
-      - psql-manager/manager.sh fixture workspace
-      - cd ..
-      - rm -rf form-creator-database
     script:
+        - apt-get update -q -y
+        - apt-get install wget gnupg -y
+        - echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main" > /etc/apt/sources.list.d/pgdg.list
+        - wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
+        - apt-get update -q -y
+        - apt-get install -y postgresql-client-10
+        - git clone --recurse-submodules https://gitlab.c3sl.ufpr.br/simmctic/form-creator/form-creator-database.git form-creator-database
+        - cd  form-creator-database
+        - psql-manager/manager.sh create workspace
+        - psql-manager/manager.sh fixture workspace
+        - cd ..
+        - rm -rf form-creator-database
         - yarn install --frozen-lockfile --silent --non-interactive
         - ln -s config.env.example config/test.env
         - yarn test
+    tags:
+        - node
+
+run_lint:
+    stage: test
+    script:
+        - yarn install --frozen-lockfile --silent --non-interactive
+        - ln -s config.env.example config/test.env
         - yarn run lint
     tags:
         - node
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7f04653bcfc2a735badcc78f03337f20f3ddbc6..d16cd2784fcb55e9dcb8b1c5e24fc019982655de 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,77 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## 1.1.0 - 11-10-2019
+### Changed
+- Create a stable version
+
+## 1.0.10 - 10-10-2019
+### Added
+- Validation type DEPENDENCY #41 (Gianfranco)
+### Changed
+- ValidateInput method to receive a vector of inputs
+
+
+## 1.0.9 - 09-10-2019
+### Added
+- Validation type MAXANSWERS #38 (Gianfranco)
+
+
+## 1.0.8 - 08-10-2019
+### Added
+- Validation type SOMECHECKBOX #39 (Gianfranco)
+### Changed
+- ValidateInput method to receive a vector of input answers
+
+
+## 1.0.7 - 01-10-2019
+### Added
+- Validation type TYPEOF #37 (Gianfranco)
+
+
+## 1.0.6 - 30-09-2019
+### Added
+- QueryBuilder Class #47 (Gianfranco)
+- FormQueryBuilder Class #47
+- AnswerQueryBuilder Class #47
+### Changed
+- DbHandler to only have database connections
+
+
+## 1.0.5 - 27-09-2019
+### Added
+- Input type Select #36 (Gianfranco)
+
+
+## 1.0.4 - 26-09-2019
+### Added
+- Input type Radio #35 (Gianfranco)
+
+
+## 1.0.3 - 24-09-2019
+### Changed
+- Refactor DbHandler #46 (Gianfranco)
+- Fix api routes
+- Set false to max-classes-per-file on tslint
+
+
+## 1.0.2 - 27-08-2019
+### Added
+- Input type Checkbox #34 (Gianfranco)
+- Sugestions for input answers
+### Changed
+- OptHandler to validate Sugestions
+- DbHandler to insert Sugestions on database
+
+
+## 1.0.1 - 20-08-2019
+### Added
+- DbHandler methods to update form table #42 (Gianfranco)
+### Changed
+- FormUpdate to receive a options changed
+- DiffHandler to recognize changes on forms
+
+
 ## 1.0.0 - 19-08-2019
 ### Changed
 - Create a stable version
diff --git a/package.json b/package.json
index eef8fd87e5eea05c61f639a7607921047210ea5e..a7c3995a0af590232a2143781af3171f85b0c8b8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "form-creator-api",
-  "version": "1.0.0",
+  "version": "1.1.0",
   "description": "RESTful API used to manage and answer forms.",
   "main": "index.js",
   "scripts": {
diff --git a/src/api/controllers/form.spec.ts b/src/api/controllers/form.spec.ts
index ef1e8a001543d3c174f087d78409ea5ab57b582a..99653d75a22c50f720d5d15960f35595b6a685b8 100644
--- a/src/api/controllers/form.spec.ts
+++ b/src/api/controllers/form.spec.ts
@@ -31,7 +31,7 @@ import { Form, FormOptions } from "../../core/form";
 import { FormUpdate, FormUpdateOptions } from "../../core/formUpdate";
 import { Input, InputOptions, Validation } from "../../core/input";
 import { InputUpdate, InputUpdateOptions } from "../../core/inputUpdate";
-import { DbHandler, QueryOptions } from "../../utils/dbHandler";
+import { DbHandler } from "../../utils/dbHandler";
 import { configs } from "../../utils/config";
 
 describe("API data controller", () => {
@@ -316,8 +316,12 @@ describe("API data controller", () => {
                         , description: 'Description Question 4 Form 3'
                         , question: 'Question 4 Form 3'
                         , enabled: true
-                        , type: InputType.TEXT
+                        , type: InputType.CHECKBOX
                         , validation: []
+                        , sugestions: [
+                            { value: "Sugestion 1", placement: 0 }
+                            , { value: "Sugestion 2", placement: 1 }
+                        ]
                         , id: undefined
                     }
                     , {
@@ -415,6 +419,116 @@ describe("API data controller", () => {
             .end(done);
     });
 
+    it("should respond 200 when putting valid form update changing the title", (done) => {
+        request(server)
+            .put("/form/4")
+            .send({
+                id: 4
+                , title: 'Title 4'
+                , description: 'Description 4'
+                , inputs: [
+                    {
+                        placement: 0
+                        , description: 'Description Question 1 Form 4'
+                        , question: 'Question 1 Form 4'
+                        , enabled: true
+                        , type: InputType.TEXT
+                        , validation: [
+                            { type: ValidationType.MANDATORY, arguments: [] }
+                        ]
+                        , id: 8
+                    }
+                    , {
+                        placement: 1
+                        , description: 'Description Question 2 Form 4'
+                        , question: 'Question 2 Form 4'
+                        , enabled: true
+                        , type: InputType.TEXT
+                        , validation: [
+                            { type: 3, arguments: [ '10' ] }
+                            , { type: 4, arguments: [ '2' ] }
+                        ]
+                        , id: 9
+                    }
+                    , {
+                        placement: 2
+                        , description: 'Description Question 3 Form 4'
+                        , question: 'Question 3 Form 4'
+                        , enabled: true
+                        , type: InputType.TEXT
+                        , validation: [
+                            { type: 3, arguments: [ '10' ] }
+                            , { type: 4, arguments: [ '2' ] }
+                        ]
+                        , id: 10
+                    }
+                ]
+            })
+        
+            .expect(200)
+            .expect((res: any) => {
+                const message = "Updated"
+                expect(res.body.message).to.be.equal(message);
+            })
+
+            .end(done);
+    });
+
+    it("should respond 200 when putting valid form update undo changes", (done) => {
+        request(server)
+            .put("/form/4")
+            .send({
+                id: 4
+                , title: 'Form Title 4'
+                , description: 'Form Description 4'
+                , inputs: [
+                    {
+                        placement: 0
+                        , description: 'Description Question 1 Form 4'
+                        , question: 'Question 1 Form 4'
+                        , enabled: true
+                        , type: InputType.TEXT
+                        , validation: [
+                            { type: ValidationType.MANDATORY, arguments: [] }
+                        ]
+                        , id: 8
+                    }
+                    , {
+                        placement: 1
+                        , description: 'Description Question 2 Form 4'
+                        , question: 'Question 2 Form 4'
+                        , enabled: true
+                        , type: InputType.TEXT
+                        , validation: [
+                            { type: 3, arguments: [ '10' ] }
+                            , { type: 4, arguments: [ '2' ] }
+                        ]
+                        , id: 9
+                    }
+                    , {
+                        placement: 2
+                        , description: 'Description Question 3 Form 4'
+                        , question: 'Question 3 Form 4'
+                        , enabled: true
+                        , type: InputType.TEXT
+                        , validation: [
+                            { type: 3, arguments: [ '10' ] }
+                            , { type: 4, arguments: [ '2' ] }
+                        ]
+                        , id: 10
+                    }
+                ]
+            })
+        
+            .expect(200)
+            .expect((res: any) => {
+                const message = "Updated"
+                expect(res.body.message).to.be.equal(message);
+            })
+
+            .end(done);
+    });
+
     it("should respond 500 when putting a valid form update for an inexistent form", (done) => {
         request(server)
             .put("/form/10")
diff --git a/src/api/controllers/form.ts b/src/api/controllers/form.ts
index df60bc1fcbbac3d04d17f08aad90c19b79f504a4..6e40357c03237def4bb4171ead70132834bb10be 100644
--- a/src/api/controllers/form.ts
+++ b/src/api/controllers/form.ts
@@ -31,7 +31,7 @@ export class FormCtrl {
 
     public static list(req: Request, res: Response, next: NextFunction) {
 
-        req.db.listForms((err: Error, forms?: Form[]) => {
+        req.db.form.list((err: Error, forms?: Form[]) => {
             if (err){
                 res.status(500).json({
                     message: "Could not list forms. Some error has occurred. Check error property for details.",
@@ -39,22 +39,20 @@ export class FormCtrl {
                 });
                 return;
             }
-            else{
-                const mappedForms = forms.map(form => ({
-                    id: form.id,
-                    title: form.title,
-                    description: form.description
-                }));
-                res.json(mappedForms);
-                return;
-            }
 
+            const mappedForms = forms.map(form => ({
+                id: form.id
+                , title: form.title
+                , description: form.description
+            }));
+            res.json(mappedForms);
+            return;
         });
-
     }
 
     public static read(req: Request, res: Response, next: NextFunction) {
-        req.db.readForm(req.params.id, (err: Error, form?: Form) => {
+
+        req.db.form.read(req.params.id, (err: Error, form?: Form) => {
             if (err){
                 res.status(500).json({
                     message: "Form with id: '"  + req.params.id + "' not found. Some error has occurred. Check error property for details.",
@@ -62,10 +60,9 @@ export class FormCtrl {
                 });
                 return;
             }
-            else{
-                res.json(form);
-                return;
-            }
+
+            res.json(form);
+            return;
         });
     }
 
@@ -83,43 +80,43 @@ export class FormCtrl {
         }
         waterfall ([
             (callback: (err: Error, result?: FormUpdate) => void) => {
-                req.db.writeForm(form, (err: Error, formResult: Form) => {
+                req.db.form.write(form, (err: Error, formResult: Form) => {
                     if (err) {
                         callback(err);
+                        return;
                     }
-                    else {
-                        const formOpts: FormOptions = {
-                            id: formResult.id
-                            , title: formResult.title
-                            , description: formResult.description
-                            , inputs: []
-                        };
-                        const formUpdate: FormUpdate = DiffHandler.diff(formResult, new Form (formOpts));
-                                  
-                        callback(null, formUpdate);
-                    }
+                    const formOpts: FormOptions = {
+                        id: formResult.id
+                        , title: formResult.title
+                        , description: formResult.description
+                        , inputs: []
+                    };
+                    const formUpdate: FormUpdate = DiffHandler.diff(formResult, new Form (formOpts));
+                    
+                    callback(null, formUpdate);
                 });
             },
             (formUpdate: FormUpdate, callback: (err: Error, formId: number) => void) => {
-                req.db.updateForm(formUpdate, (err: Error) => {
+                req.db.form.update(formUpdate, (err: Error) => {
                         callback(err, formUpdate.form.id);
                 });
             }
         ], (err, resultId) => {
             if (err) {
                 res.status(500).json({
-                    message: "Could not insert form. Some error has occurred. Check error property for details.",
-                    error: err.message
-                });
-            }
-            else {
-                res.json({
-                    id: resultId
-                    , message: "Form added. Id on key 'id'"
+                    message: "Could not insert form. Some error has occurred. Check error property for details."
+                    , error: err.message
                 });
+                return;
             }
+            
+            res.json({
+                id: resultId
+                , message: "Form added. Id on key 'id'"
+            });
             return;
         });
+
     }
 
     public static update(req: Request, res: Response, next: NextFunction) {
@@ -129,48 +126,36 @@ export class FormCtrl {
             newForm = new Form(OptHandler.form(req.body));
         } catch(e) {
             res.status(500).json({
-                message: "Invalid Form. Check error property for details.",
-                error: e.message
+                message: "Invalid Form. Check error property for details."
+                , error: e.message
             });
             return;
         }
         waterfall([
             (callback: (err: Error, result?: FormUpdate) => void) => {
-                req.db.readForm(req.params.id, (err: Error, oldForm: Form) => {
+                req.db.form.read(req.params.id, (err: Error, oldForm: Form) => {
                     if (err) {
                         callback(err);
+                        return;
                     }
-                    else {
-                        const formUpdate: FormUpdate = DiffHandler.diff(newForm, oldForm);
-                        callback(null, formUpdate);
-                    }
+                    
+                    const formUpdate: FormUpdate = DiffHandler.diff(newForm, oldForm);
+                    
+                    callback(null, formUpdate);
                 });
             },
             (formUpdate: FormUpdate, callback: (err: Error, formUpdateResult?: FormUpdate) => void) => {
-                req.db.updateDatabase(formUpdate, (err: Error, formUpdateResult: FormUpdate) => {
-                    if (err) {
-                        callback(err);
-                    }
-                    callback(null,formUpdateResult);
-                });
-            },
-            (formUpdate: FormUpdate, callback: (err: Error) => void) => {
-                req.db.updateForm(formUpdate, (err: Error) => {
-                    callback(err);
-                });
+                req.db.form.update(formUpdate, callback);
             }
         ], (err) => {
             if (err) {
                 res.status(500).json({
-                    message: "Could not update Form. Some error has ocurred. Check error property for details.",
-                    error: err.message
-                });
-            }
-            else {
-                res.json({
-                    message: "Updated"
+                    message: "Could not update Form. Some error has ocurred. Check error property for details."
+                    , error: err.message
                 });
+                return;
             }
+            res.json({ message: "Updated" });
             return;
         });
     }
diff --git a/src/api/controllers/formAnswer.spec.ts b/src/api/controllers/formAnswer.spec.ts
index c88b2f0e621e89745952d51bb65dd9737ff83b56..cda55f53579940805607b369325fa8954da09416 100644
--- a/src/api/controllers/formAnswer.spec.ts
+++ b/src/api/controllers/formAnswer.spec.ts
@@ -19,54 +19,72 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
- import * as request from "supertest";
- import { expect } from "chai";
- import * as server from "../../main";
- import { EnumHandler,InputType, ValidationType } from "../../utils/enumHandler";
- import { TestHandler } from "../../utils/testHandler";
- import { OptHandler } from "../../utils/optHandler";
- import { Form, FormOptions } from "../../core/form";
- import { Input, InputOptions, Validation } from "../../core/input";
+import * as request from "supertest";
+import { expect } from "chai";
+import * as server from "../../main";
+import { EnumHandler,InputType, ValidationType } from "../../utils/enumHandler";
+import { TestHandler } from "../../utils/testHandler";
+import { OptHandler } from "../../utils/optHandler";
+import { Form, FormOptions } from "../../core/form";
+import { Input, InputOptions, Validation } from "../../core/input";
 
 
- describe("API data controller", () => {
+describe("API data controller", () => {
 
-        it("should respond 200 when posting valid form Answer", (done) => {
+    it("should respond 200 when posting valid form Answer", (done) => {
 
-             request(server)
-                 .post("/answer/1")
-                 .send({
-                     1:["Answer to Question 1 Form 1"]
-                     , 2:["12345-000"]
-                     , 3:["MAXCHAR 10"]
-                })
-                .expect(200)
-                .expect((res: any) => {
-                    expect(res.body.id).to.be.equal(7);
-                    expect(res.body.message).to.be.equal("Answered");
-                })
-                .end(done);
-        });
+        request(server)
+            .post("/answer/1")
+            .send({
+                1:["Answer to Question 1 Form 1"]
+                , 2:["12345-000"]
+                , 3:["MAXCHAR 10"]
+            })
+            .expect(200)
+            .expect((res: any) => {
+                expect(res.body.id).to.be.equal(7);
+                expect(res.body.message).to.be.equal("Answered");
+            })
+            .end(done);
+    });
 
-        it("should respond 500 when posting invalid form Answer", (done) => {
+    it("should respond 500 when posting invalid form Answer", (done) => {
 
-             request(server)
-                 .post("/answer/1")
-                 .send({
-                     1:["Answer to Question 1 Form 1"]
-                     , 2:["12a345-000"]
-                     , 3:["MAXCHAR 10 AND MORE"]
-                })
-                .expect(500)
-                .expect((res: any) => {
-                    const message = "Could not Create form Answer. Some error has occurred. Check error property for details.";
-                    expect(res.body).to.be.an("object");
-                    expect(res.body).to.have.property("error");
-                    expect(res.body.message).to.be.equal(message);
-                    expect(res.body.error["2"]).to.be.equal("RegEx do not match");
-                    expect(res.body.error["3"]).to.be.equal("Input answer must be lower than 10");
-                })
-                .end(done);
-        });
+        request(server)
+            .post("/answer/1")
+            .send({
+                1:["Answer to Question 1 Form 1"]
+                , 2:["12a345-000"]
+                , 3:["MAXCHAR 10 AND MORE"]
+            })
+            .expect(500)
+            .expect((res: any) => {
+                const message = "Could not Create form Answer. Some error has occurred. Check error property for details.";
+                expect(res.body).to.be.an("object");
+                expect(res.body).to.have.property("error");
+                expect(res.body.message).to.be.equal(message);
+                expect(res.body.error["2"]).to.be.equal("RegEx do not match");
+                expect(res.body.error["3"]).to.be.equal("Input answer must be lower than 10");
+            })
+            .end(done);
+    });
 
- });
+    it("should respond 500 when posting valid form Answer for a invalid Form", (done) => {
+
+        request(server)
+            .post("/answer/10")
+            .send({
+                1:["Answer to Question 1 Form 1"]
+                , 2:["12a345-000"]
+                , 3:["MAXCHAR 10 AND MORE"]
+            })
+            .expect(500)
+            .expect((res: any) => {
+                const message = "Form with id: '10' not found. Some error has occurred. Check error property for details.";
+                expect(res.body).to.be.an("object");
+                expect(res.body).to.have.property("error");
+                expect(res.body.message).to.be.equal(message);
+            })
+            .end(done);
+    });
+});
diff --git a/src/api/controllers/formAnswer.ts b/src/api/controllers/formAnswer.ts
index 9549a66dd1c643f57f29b9e6e0f636c6b89658e1..226068460d301a8519e42ded9deab3460bbfacd5 100644
--- a/src/api/controllers/formAnswer.ts
+++ b/src/api/controllers/formAnswer.ts
@@ -31,72 +31,64 @@ export class AnswerCtrl {
 
     public static write(req: Request, res: Response, next: NextFunction) {
 
-        req.db.readForm(req.params.id, (err: Error, form?: Form) => {
+        req.db.form.read(req.params.id, (err: Error, form?: Form) => {
             if (err) {
                 res.status(500).json({
-                    message: "Form with id: '" + req.params.id + "' not found. Some error has occurred. Check error property for details.",
-                    error: err
+                    message: "Form with id: '" + req.params.id + "' not found. Some error has occurred. Check error property for details."
+                    , error: err
                 });
                 return;
             }
-            else {
-                let inputAnswerOptionsDict: InputAnswerOptionsDict = {}
+            
+            let inputAnswerOptionsDict: InputAnswerOptionsDict = {}
 
-                for (const key of Object.keys(req.body)) {
-                    inputAnswerOptionsDict[parseInt(key, 10)] = [];
-                    for (const i in req.body[key]) {
-                        const tmpInputAnswerOption: InputAnswerOptions = {
-                            idInput: parseInt(key, 10)
-                            , placement: parseInt(i, 10)
-                            , value: req.body[key][i]
-                        }
-                        inputAnswerOptionsDict[parseInt(key, 10)].push(tmpInputAnswerOption);
+            for (const key of Object.keys(req.body)) {
+                inputAnswerOptionsDict[parseInt(key, 10)] = [];
+                for (const i in req.body[key]) {
+                    const tmpInputAnswerOption: InputAnswerOptions = {
+                        idInput: parseInt(key, 10)
+                        , placement: parseInt(i, 10)
+                        , value: req.body[key][i]
                     }
+                    inputAnswerOptionsDict[parseInt(key, 10)].push(tmpInputAnswerOption);
                 }
+            }
 
+            let formAnswerOpt: FormAnswerOptions = {
+                form: form
+                , timestamp: new Date(Date.now())
+                , inputsAnswerOptions: inputAnswerOptionsDict
+            }
 
-                let formAnswerOpt: FormAnswerOptions = {
-                    form: form
-                    , timestamp: new Date(Date.now())
-                    , inputsAnswerOptions: inputAnswerOptionsDict
-                }
-
-                try{
-                    const formAnswer: FormAnswer = new FormAnswer(OptHandler.formAnswer(formAnswerOpt));
-                    ValidationHandler.validateFormAnswer(formAnswer);
-                    req.db.writeFormAnswer(formAnswer, (err: Error, formAnswerResult: FormAnswer) => {
-                        if (err){
-                            throw err;
-                        }
-                        else{
-                            res.json({
-                                id: formAnswerResult.id
-                                , message: "Answered"
-                            });
-                           return;
-                        }
+            try {
+                const formAnswer: FormAnswer = new FormAnswer(OptHandler.formAnswer(formAnswerOpt));
+                ValidationHandler.validateFormAnswer(formAnswer);
+                req.db.answer.write(formAnswer, (err: Error, formAnswerResult: FormAnswer) => {
+                    if (err){
+                        throw err;
+                        return;
+                    } 
+                    res.json({
+                        id: formAnswerResult.id
+                        , message: "Answered"
                     });
-                }
-                catch (e) {
-
-                    if( e.validationDict !== undefined){
-                        res.status(500).json({
-                            message: "Could not Create form Answer. Some error has occurred. Check error property for details."
-                            , error: e.validationDict
-                        });
-                    }else{
-                        res.status(500).json({
-                            message: "Could not Create form Answer. Some error has occurred. Check error property for details."
-                            , error: e.message
-                        });
-                    }
-                    return
-                }
+                    return;
+                });
+            } catch (e) {
+                if (e.validationDict !== undefined) {
+                    res.status(500).json({
+                        message: "Could not Create form Answer. Some error has occurred. Check error property for details."
+                        , error: e.validationDict
+                    });
+                    return;
+                } 
 
+                res.status(500).json({
+                    message: "Could not Create form Answer. Some error has occurred. Check error property for details."
+                    , error: e.message
+                });
+                return;
             }
         });
-
     }
-
-
 }
diff --git a/src/core/formUpdate.ts b/src/core/formUpdate.ts
index 5ee927dce8b5cbe52e8052a7df0c84742653477f..4091c307dcf511c3ba73e0f741d351effbcf0ab7 100644
--- a/src/core/formUpdate.ts
+++ b/src/core/formUpdate.ts
@@ -26,10 +26,12 @@ import { InputUpdate, InputUpdateOptions } from "./inputUpdate";
 export interface FormUpdateOptions {
     /** Unique identifier of a FormUpdate instance. */
     id?: number;
-    /**  Changed Form. */
+    /** Changed Form. */
     form: FormOptions;
     /** Date which form was updated. */
     updateDate: Date;
+    /** True when Form title or description has changed. */
+    changed?: boolean;
     /** Array of InputUpdate containing changes on inputs. */
     inputUpdates: InputUpdateOptions[];
 }
@@ -44,6 +46,8 @@ export class FormUpdate {
     public readonly form: Form;
     /** Date which form was updated. */
     public readonly updateDate: Date;
+    /** True when Form title or description has changed. */
+    public readonly changed?: boolean;
     /** Array of InputUpdate containing changes on inputs. */
     public readonly inputUpdates: InputUpdate[];
     /**
@@ -54,6 +58,7 @@ export class FormUpdate {
         this.id = options.id ? options.id : null;
         this.form = new Form (options.form);
         this.updateDate = options.updateDate;
+        this.changed = options.changed ? options.changed : false;
         this.inputUpdates = options.inputUpdates.map((i: any) => {
             return new InputUpdate(i);
         });
diff --git a/src/core/input.ts b/src/core/input.ts
index f7097aa46aede4916908aa5a513db39bb8b9c5fa..c199c378fe37c9c3d11af2780f71fd861b3de3b1 100644
--- a/src/core/input.ts
+++ b/src/core/input.ts
@@ -24,19 +24,21 @@ import { InputType, ValidationType } from "../utils/enumHandler";
 /** Parameters used to create a input object. */
 export interface InputOptions {
     /** Unique identifier of a Input instance. */
-     id?: number;
+    id?: number;
     /** Place where input should be in the form. */
-     placement: number;
+    placement: number;
     /** Input's Description */
-     description: string;
+    description: string;
     /** Question of input */
-     question: string;
+    question: string;
     /** Enabled/Disable input */
-     enabled?: boolean;
+    enabled?: boolean;
     /** Type of input */
-     type: InputType;
+    type: InputType;
     /** Array contain all input's validation */
-     validation: Validation[];
+    validation: Validation[];
+    /** Question answer sugestion */
+    sugestions?: Sugestion[];
 }
 /** Validation contains the type of it, and n arguments to validate if necessary */
 export interface Validation {
@@ -47,10 +49,17 @@ export interface Validation {
     arguments: string[];
 }
 
+/** Sugestion for answers */
+export interface Sugestion {
+    /** Answer's sugestion for a input */
+    value: string;
+    /** Place where sugestion should be in the input */
+    placement: number;
+}
+
 /**
  * Input Class to manage project's inputs forms
  */
-
 export class Input {
     /** Unique identifier of a Input instance. */
     public readonly id: number;
@@ -66,6 +75,8 @@ export class Input {
     public readonly type: InputType;
     /** Array contain all input's validation */
     public readonly validation: Validation[];
+    /** Question answer sugestions */
+    public readonly sugestions?: Sugestion[];
 
     /**
      * Creates a new instance of Input Class
@@ -83,7 +94,12 @@ export class Input {
             this.enabled = options.enabled;
         }
         this.type = options.type;
+        if (options.sugestions) {
+            this.sugestions = options.sugestions.map((i: any) => i);
+        }
+        else {
+            this.sugestions = [];
+        }
         this.validation = options.validation;
     }
-
 }
diff --git a/src/utils/answerQueryBuilder.ts b/src/utils/answerQueryBuilder.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8363e93f4723ba35cdabcd37e51fcb2d985881ce
--- /dev/null
+++ b/src/utils/answerQueryBuilder.ts
@@ -0,0 +1,357 @@
+/*
+ * form-creator-api. RESTful API to manage and answer forms.
+ * Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+ *
+ * This file is part of form-creator-api.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import { eachSeries, map, waterfall } from "async";
+import { Pool, PoolConfig, QueryResult } from "pg";
+import { Form, FormOptions } from "../core/form";
+import { FormAnswer, FormAnswerOptions } from "../core/formAnswer";
+import { Input, InputOptions } from "../core/input";
+import { InputAnswer, InputAnswerDict, InputAnswerOptions, InputAnswerOptionsDict } from "../core/inputAnswer";
+import { EnumHandler, InputType } from "./enumHandler";
+import { ErrorHandler} from "./errorHandler";
+import { FormQueryBuilder } from "./formQueryBuilder";
+import { OptHandler } from "./optHandler";
+import { QueryBuilder, QueryOptions } from "./queryBuilder";
+import { Sorter } from "./sorter";
+/**
+ * Class used to manage all the Answer operations into the database.
+ * This operations include read and write data.
+ */
+export class AnswerQueryBuilder extends QueryBuilder {
+
+    private formQueryBuilder: FormQueryBuilder;
+
+    constructor(builder: FormQueryBuilder, pool: Pool) {
+        super(pool);
+        this.formQueryBuilder = builder;
+   }
+
+    /**
+     * Asynchronously write a Answer on database.
+     * @param formAnswer - FormAnswer to be inserted.
+     * @param cb - Callback function which contains the inserted data.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.form - FormAnswer or null if any error occurs.
+     */
+    public write(formAnswer: FormAnswer, cb: (err: Error, result?: FormAnswer) => void) {
+
+        waterfall([
+            (callback: (err: Error, result?: QueryResult) =>  void) => {
+                this.begin((error: Error, results?: QueryResult) => {
+                    callback(error);
+                });
+            },
+
+            (callback: (err: Error, result?: number) => void) => {
+                this.writeController(formAnswer, (error: Error, resultAnswerId?: number) => {
+                    callback(error, resultAnswerId);
+                });
+            },
+
+            (formAnswerId: number, callback: (err: Error, result?: number) => void) => {
+                this.commit((error: Error, results?: QueryResult) => {
+                    callback(error, formAnswerId);
+                });
+            },
+            (formAnswerId: number, callback: (err: Error, result?: FormAnswer) => void) => {
+                this.read(formAnswerId, (error: Error, formAnswerResult?: FormAnswer) => {
+                    callback(error, formAnswerResult);
+                });
+            }
+
+        ], (err, formAnswerResult?: FormAnswer) => {
+            if (err) {
+                this.rollback((error: Error, results?: QueryResult) => {
+                    cb(err);
+                });
+                return;
+            }
+            cb(null, formAnswerResult);
+        });
+    }
+
+    /**
+     * Asynchronously write a Answer on database without transactions.
+     * @param formAnswer - FormAnswer identifier to be inserted.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.form - FormAnswer identifier or null if any error occurs.
+     */
+    private writeController(formAnswer: FormAnswer, cb: (err: Error, result?: number) => void) {
+        waterfall([
+            (callback: (err: Error, result?: any) => void) => {
+                this.executeWriteForm(formAnswer, (error: Error, resultId?: number) => {
+                    if (error) {
+                        callback(error);
+                        return;
+                    }
+                    callback(null, resultId);
+                });
+            },
+            (formAnswerId: number, callback: (err: Error, result?: any) => void) => {
+                eachSeries(Object.keys(formAnswer.inputAnswers), (key, outerCallback) => {
+                    eachSeries(formAnswer.inputAnswers[parseInt(key, 10)], (inputsAnswer, innerCallback) => {
+                        this.executeWriteInput(formAnswerId, inputsAnswer, innerCallback);
+                    }, (error) => {
+                        outerCallback(error);
+                    });
+                }, (err, id?: number) => {
+                    callback(err, formAnswerId);
+                });
+            }
+        ], (err, id?: number) => {
+            cb(err, id);
+        });
+    }
+
+    /**
+     * Asynchronously insert a FormAnswer on database.
+     * @param formAnswer - FormAnswer to be inserted.
+     * @param cb - Callback function.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.result - FormAnswer identifier or null if any error occurs.
+     */
+    private executeWriteForm(formAnswer: FormAnswer, cb: (err: Error, result?: number) => void) {
+        const queryString: string = "INSERT INTO form_answer (id_form, answered_at) \
+                                     VALUES( $1, $2 ) \
+                                     RETURNING id;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [
+                formAnswer.form.id
+                , formAnswer.timestamp
+            ]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            if (err){
+                cb(err);
+                return;
+            }
+
+            if (result.rowCount !== 1){
+                cb(ErrorHandler.notInserted("FormAnswer"));
+                return;
+            }
+            cb(null, result.rows[0]["id"]);
+        });
+    }
+
+    /**
+     * Asynchronously insert a inputAnswer on database.
+     * @param formAnswerId - Indentifier to relate with InputAnswer.
+     * @param cb - Callback function.
+     * @param cb.err - Error information when the method fails.
+     */
+    private executeWriteInput(formAnswerId: number, inputAnswer: InputAnswer, cb: (err: Error) => void) {
+        const queryString: string = "INSERT INTO input_answer (id_form_answer, id_input, value, placement) \
+                                     VALUES ( $1, $2, $3, $4) \
+                                     RETURNING id;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [
+                formAnswerId
+                , inputAnswer.idInput
+                , inputAnswer.value
+                , inputAnswer.placement
+            ]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            if (err){
+                cb(err);
+                return;
+            }
+
+            if (result.rowCount !== 1){
+                cb(ErrorHandler.notInserted("InputsAnswer"));
+                return;
+            }
+            cb(null);
+        });
+    }
+
+    /**
+     * Asynchronously read a FormAnswer from database.
+     * @param formAnswerId - FormAnswer identifier to be founded.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.formAnswers - FormAnswer object or null if form not exists.
+     */
+    public read(formAnswerId: number, cb: (err: Error, formAnswers?: FormAnswer) => void) {
+        waterfall([
+            (callback: (err: Error, result?: QueryResult) =>  void) => {
+                this.begin((error: Error, results?: QueryResult) => {
+                    callback(error);
+                });
+            },
+            (callback: (err: Error, result?: FormAnswer) => void) => {
+                this.readController(formAnswerId, (error: Error, resultAnswer?: FormAnswer) => {
+                    callback(error, resultAnswer);
+                });
+            },
+            (formAnswer: FormAnswer, callback: (err: Error, result?: FormAnswer) => void) => {
+                this.commit((error: Error, results?: QueryResult) => {
+                    callback(error, formAnswer);
+                });
+            },
+            (formAnswer: FormAnswer, callback: (err: Error, result?: FormAnswer) => void) => {
+                this.formQueryBuilder.read(formAnswer.form.id, (error: Error, resultForm?: Form) => {
+                    const formAnswerObj: FormAnswer = {
+                        id: formAnswer.id
+                        , form: resultForm
+                        , timestamp: formAnswer.timestamp
+                        , inputAnswers: formAnswer.inputAnswers
+                    };
+                    callback(error, formAnswerObj);
+                });
+            }
+        ], (err, formAnswer?: FormAnswer) => {
+            if (err) {
+                this.rollback((error: Error, results?: QueryResult) => {
+                    cb(err);
+                });
+                return;
+            }
+            cb(null, formAnswer);
+        });
+    }
+
+    /**
+     * Asynchronously read a FormAnswer from database without transaction.
+     * @param formAnswerId - FormAnswer identifier to be founded.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.result - FormAnswer object or null if FormAnswer not exists.
+     */
+    private readController(formAnswerId: number, cb: (err: Error, result?: FormAnswer) => void) {
+        waterfall([
+            (callback: (err: Error, result?: InputAnswerOptionsDict) => void) => {
+                this.executeReadInput(formAnswerId, (err: Error, result?: QueryResult) => {
+                    if (err) {
+                        cb(err);
+                        return;
+                    }
+                    const inputAnswersOpts: InputAnswerOptions[] = result.rows.map((inputsAnswerResult) => {
+                        const inputAnswersOpt: InputAnswerOptions = {
+                            id: inputsAnswerResult["id"]
+                            , idInput: inputsAnswerResult["id_input"]
+                            , value: inputsAnswerResult["value"]
+                            , placement: inputsAnswerResult["placement"]
+                        };
+                        return OptHandler.inputAnswer(inputAnswersOpt);
+                    });
+
+                    const inputsAnswerResults: InputAnswerOptionsDict = {};
+                    for (const i of inputAnswersOpts){
+                        if (inputsAnswerResults[i["idInput"]]) {
+                            inputsAnswerResults[i["idInput"]].push(i);
+                            inputsAnswerResults[i["idInput"]] = Sorter.sortByPlacement(inputsAnswerResults[i["idInput"]]);
+                        } else {
+                            inputsAnswerResults[i["idInput"]] = [i];
+                        }
+                    }
+
+                    callback(err, inputsAnswerResults);
+                });
+            },
+            (inputsAnswerResults: InputAnswerOptionsDict, callback: (err: Error, result?: FormAnswer) => void) => {
+                this.executeReadForm(formAnswerId, (error: Error, answerResult?: any) => {
+                    if (error) {
+                        callback(error);
+                        return;
+                    }
+                    const formTmp: Form = {
+                        id: answerResult.id_form
+                        , title: undefined
+                        , description: undefined
+                        , inputs: []
+                    };
+                    const formAnswerTmp: FormAnswerOptions = {
+                        id: answerResult.id
+                        , form: formTmp
+                        , timestamp: answerResult.answered_at
+                        , inputsAnswerOptions: inputsAnswerResults
+                    };
+
+                    callback(null, new FormAnswer(formAnswerTmp));
+                });
+            }
+        ], (err, formAnswer: FormAnswer) => {
+            if (err) {
+                cb(err);
+                return;
+            }
+            cb(null, formAnswer);
+        });
+    }
+
+    /**
+     * Asynchronously read a formAnswer from database.
+     * @param formUpdate - FormAnswer identifier to be founded.
+     * @param cb - Callback function.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.result - The read FormAnswer result query row.
+     */
+    private executeReadForm(formAnswerId: number, cb: (err: Error, result?: QueryResult) => void) {
+        const queryString: string = "SELECT id, id_form, answered_at \
+                                     FROM form_answer \
+                                     WHERE id=$1;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [formAnswerId]
+        };
+
+        this.executeQuery(query, (error: Error, result?: QueryResult) => {
+            if (result.rowCount !== 1) {
+                cb(ErrorHandler.badIdAmount(result.rowCount));
+                return;
+            }
+
+            cb(error, result.rows[0]);
+        });
+    }
+
+    /**
+     * Asynchronously read a InputAnswer from database.
+     * @param formAnswerId - Identifier to read InputAnswers.
+     * @param cb - Callback function.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.result - The read InputAnswer result query.
+     */
+    private executeReadInput(formAnswerId: number, cb: (err: Error, result?: QueryResult) => void) {
+        const queryString: string = "SELECT id, id_form_answer, id_input, value, placement \
+                                     FROM input_answer \
+                                     WHERE id_form_answer=$1;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [formAnswerId]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            if (err) {
+                cb(err);
+                return;
+            }
+            cb(null, result);
+        });
+    }
+}
diff --git a/src/utils/dbHandler.spec.ts b/src/utils/dbHandler.spec.ts
index 441b866e4f6187196bf6cbde6d578f0a12a32486..d9301a62bde28b94dd7fe579d1bd3e272f3d9d52 100644
--- a/src/utils/dbHandler.spec.ts
+++ b/src/utils/dbHandler.spec.ts
@@ -28,9 +28,10 @@ import { Input, InputOptions, Validation } from "../core/input";
 import { InputAnswer, InputAnswerDict, InputAnswerOptions, InputAnswerOptionsDict } from "../core/inputAnswer";
 import { InputUpdate, InputUpdateOptions } from "../core/inputUpdate";
 import { configs } from "./config";
-import { DbHandler, QueryOptions } from "./dbHandler";
+import { DbHandler } from "./dbHandler";
 import { InputType, UpdateType, ValidationType } from "./enumHandler";
 import { OptHandler } from "./optHandler";
+import { QueryBuilder, QueryOptions } from "./queryBuilder";
 import { TestHandler } from "./testHandler";
 
 describe("Database Handler", () => {
@@ -38,9 +39,9 @@ describe("Database Handler", () => {
 
     it("should insert a form", (done) => {
         const queryString: string = "INSERT INTO form(id, title, description)\
-            VALUES (5, 'Form Title 5', 'Form Description 5');";
+        VALUES (5, 'Form Title 5', 'Form Description 5');";
         const query: QueryOptions = {query: queryString, parameters: []};
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("INSERT");
             expect(result.rowCount).to.be.equal(1);
@@ -52,17 +53,17 @@ describe("Database Handler", () => {
     it("should insert a form and then rollback", (done) => {
     series([
         (cb: (err: Error, result?: QueryResult) =>  void) => {
-            dbhandler.begin(cb);
+            dbhandler.form.begin(cb);
         },
         (callback: (err: Error, result?: QueryResult) =>  void) => {
             const queryString: string = "INSERT INTO form(id, title, description)\
             VALUES (6, 'Form Title 6', 'Form Description 6');";
             const query: QueryOptions = {query: queryString, parameters: []};
 
-            dbhandler.executeQuery(query, callback);
+            dbhandler.form.executeQuery(query, callback);
         },
         (cb: (err: Error, result?: QueryResult) =>  void) => {
-            dbhandler.rollback(cb);
+            dbhandler.form.rollback(cb);
         }
     ], (err, results) => {
 
@@ -79,7 +80,7 @@ describe("Database Handler", () => {
     it("should select all forms", (done) => {
         const queryString: string = "SELECT * FROM form;";
         const query: QueryOptions = {query: queryString, parameters: []};
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("SELECT");
             expect(result.rowCount).to.be.equal(5);
@@ -93,7 +94,7 @@ describe("Database Handler", () => {
 
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
             expect(result.rowCount).to.be.equal(0);
@@ -105,7 +106,7 @@ describe("Database Handler", () => {
     it("should remove existent form", (done) => {
         const queryString: string = "DELETE FROM form WHERE id=5;";
         const query: QueryOptions = {query: queryString, parameters: []};
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
             expect(result.rowCount).to.be.equal(1);
@@ -120,7 +121,7 @@ describe("Database Handler", () => {
         (2, 3,'TEXT', TRUE, 'Question 3 Form 2', 'Description Question 3 Form 2'),\
         (2, 4,'TEXT', TRUE, 'Question 4 Form 2', 'Description Question 4 Form 2');";
         const query: QueryOptions = {query: queryString, parameters: []};
-        dbhandler.executeQuery(query,  (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query,  (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("INSERT");
             expect(result.rowCount).to.be.equal(2);
@@ -132,7 +133,7 @@ describe("Database Handler", () => {
         const queryString: string = "SELECT * FROM input;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("SELECT");
             expect(result.rowCount).to.be.equal(15);
@@ -145,7 +146,7 @@ describe("Database Handler", () => {
         const queryString: string = "DELETE FROM input WHERE id=20;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) =>  {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) =>  {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
             expect(result.rowCount).to.be.equal(0);
@@ -154,13 +155,13 @@ describe("Database Handler", () => {
     });
 
     it("should remove existent input", (done) => {
-        const queryString: string = "DELETE FROM input WHERE id=12 OR id=13 OR id=14 OR id=15;";
+        const queryString: string = "DELETE FROM input WHERE id=9 OR id=14 OR id=15;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
-            expect(result.rowCount).to.be.equal(4);
+            expect(result.rowCount).to.be.equal(3);
             done();
 
         });
@@ -173,7 +174,7 @@ describe("Database Handler", () => {
         (5, 'MANDATORY');";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("INSERT");
             expect(result.rowCount).to.be.equal(2);
@@ -185,10 +186,10 @@ describe("Database Handler", () => {
         const queryString: string = "SELECT * FROM input_validation;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("SELECT");
-            expect(result.rowCount).to.be.equal(18);
+            expect(result.rowCount).to.be.equal(14);
             done();
         });
     });
@@ -197,7 +198,7 @@ describe("Database Handler", () => {
         const queryString: string = "DELETE FROM input_validation WHERE id=21;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
             expect(result.rowCount).to.be.equal(0);
@@ -206,13 +207,13 @@ describe("Database Handler", () => {
     });
 
     it("should remove existent input validations", (done) => {
-        const queryString: string = "DELETE FROM input_validation WHERE id=17 OR id=18;";
+        const queryString: string = "DELETE FROM input_validation WHERE id=9 OR id=10 OR id=13 OR id=14;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
-            expect(result.rowCount).to.be.equal(2);
+            expect(result.rowCount).to.be.equal(4);
             done();
         });
     });
@@ -224,7 +225,7 @@ describe("Database Handler", () => {
         (2, 2, '2');";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("INSERT");
             expect(result.rowCount).to.be.equal(2);
@@ -237,10 +238,10 @@ describe("Database Handler", () => {
         const queryString: string = "SELECT * FROM input_validation_argument;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("SELECT");
-            expect(result.rowCount).to.be.equal(13);
+            expect(result.rowCount).to.be.equal(9);
             done();
         });
     });
@@ -249,7 +250,7 @@ describe("Database Handler", () => {
         const queryString: string = "DELETE FROM input_validation_argument WHERE id=15;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
             expect(result.rowCount).to.be.equal(0);
@@ -258,13 +259,13 @@ describe("Database Handler", () => {
     });
 
     it("should remove existent input validations arguments", (done) => {
-        const queryString: string = "DELETE FROM input_validation_argument WHERE id=12 OR id=13;";
+        const queryString: string = "DELETE FROM input_validation_argument WHERE id=6;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.form.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
-            expect(result.rowCount).to.be.equal(2);
+            expect(result.rowCount).to.be.equal(1);
             done();
         });
     });
@@ -276,7 +277,7 @@ describe("Database Handler", () => {
         (9, 3, '2018-06-03 10:11:25-03');";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.answer.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("INSERT");
             expect(result.rowCount).to.be.equal(2);
@@ -288,7 +289,7 @@ describe("Database Handler", () => {
         const queryString: string = "SELECT * FROM form_answer;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.answer.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("SELECT");
             expect(result.rowCount).to.be.equal(9);
@@ -300,7 +301,7 @@ describe("Database Handler", () => {
         const queryString: string = "DELETE FROM form_answer WHERE id=11;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.answer.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
             expect(result.rowCount).to.be.equal(0);
@@ -312,7 +313,7 @@ describe("Database Handler", () => {
         const queryString: string = "DELETE FROM form_answer WHERE id=8 OR id=9;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.answer.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
             expect(result.rowCount).to.be.equal(2);
@@ -328,7 +329,7 @@ describe("Database Handler", () => {
         (19,1, 7,'Answer to Question 2 Form 3',2);";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.answer.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("INSERT");
             expect(result.rowCount).to.be.equal(2);
@@ -340,7 +341,7 @@ describe("Database Handler", () => {
         const queryString: string = "SELECT * FROM input_answer;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.answer.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("SELECT");
             expect(result.rowCount).to.be.equal(19);
@@ -352,7 +353,7 @@ describe("Database Handler", () => {
         const queryString: string = "DELETE FROM input_answer WHERE id=25;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.answer.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
             expect(result.rowCount).to.be.equal(0);
@@ -364,7 +365,7 @@ describe("Database Handler", () => {
         const queryString: string = "DELETE FROM input_answer WHERE id=18 OR id=19;";
         const query: QueryOptions = {query: queryString, parameters: []};
 
-        dbhandler.executeQuery(query, (err: Error, result?: QueryResult) => {
+        dbhandler.answer.executeQuery(query, (err: Error, result?: QueryResult) => {
             expect(err).to.be.a("null");
             expect(result.command).to.be.equal("DELETE");
             expect(result.rowCount).to.be.equal(2);
@@ -374,9 +375,10 @@ describe("Database Handler", () => {
 });
 
 describe("Read and Write on Database", () => {
+
     const dbhandler = new DbHandler(configs.poolconfig);
     it("should list all forms", (done) => {
-        dbhandler.listForms((err: Error, forms?: Form[]) => {
+        dbhandler.form.list((err: Error, forms?: Form[]) => {
             expect(err).to.be.a("null");
             expect(forms.length).to.be.equal(4);
             for (let i = 0; i < forms.length; i++){
@@ -389,7 +391,8 @@ describe("Read and Write on Database", () => {
     });
 
     it("should read an existent form", (done) => {
-        dbhandler.readForm(1, (err: Error, form: Form) => {
+        dbhandler.form.read(1, (err: Error, form: Form) => {
+
             expect(err).to.be.a("null");
 
             const inputObj1: InputOptions = {
@@ -398,10 +401,24 @@ describe("Read and Write on Database", () => {
                 , question: "Question 1 Form 1"
                 , type: InputType.TEXT
                 , validation: []
+                , sugestions: []
                 , id: 1
             };
 
             const inputObj2: InputOptions = {
+                placement: 1
+                , description: "Description Question 3 Form 1"
+                , question: "Question 3 Form 1"
+                , type: InputType.TEXT
+                , validation: [
+                    { type: ValidationType.REGEX, arguments: ["\\d{5}-\\d{3}"] }
+                    , { type: ValidationType.MANDATORY, arguments: [] }
+                ]
+                , sugestions: []
+                , id: 2
+            };
+
+            const inputObj3: InputOptions = {
                 placement: 2
                 , description: "Description Question 2 Form 1"
                 , question:  "Question 2 Form 1"
@@ -410,42 +427,29 @@ describe("Read and Write on Database", () => {
                     { type: ValidationType.MAXCHAR, arguments: ["10"] }
                     , { type: ValidationType.MINCHAR, arguments: ["2"] }
                 ]
+                , sugestions: []
                 , id: 3
             };
 
-            const inputObj3: InputOptions = {
-                placement: 1
-                , description: "Description Question 3 Form 1"
-                , question: "Question 3 Form 1"
-                , type: InputType.TEXT
-                , validation: [
-                    { type: ValidationType.REGEX, arguments: ["\\d{5}-\\d{3}"] }
-                    , { type: ValidationType.MANDATORY, arguments: [] }
-                ]
-                , id: 2
-            };
             const formObj: FormOptions = {
                 id: 1
                 , title: "Form Title 1"
                 , description: "Form Description 1"
                 , inputs: [
                     OptHandler.input(inputObj1)
-                    , OptHandler.input(inputObj3)
                     , OptHandler.input(inputObj2)
+                    , OptHandler.input(inputObj3)
                 ]
             };
-
-            TestHandler.testForm(form, new Form(OptHandler.form(formObj)));
-
+            TestHandler.testForm(form, new Form(formObj));
             done();
         });
     });
 
     it("should read a non existent form", (done) => {
-        dbhandler.readForm(10, (err: Error, form: Form) => {
-            expect(err).to.not.equal(null);
+        dbhandler.form.read(10, (err: Error, form?: Form) => {
+            expect(err).to.be.not.equal(null);
             expect(form).to.be.undefined;
-
             done();
         });
     });
@@ -484,7 +488,7 @@ describe("Read and Write on Database", () => {
         };
 
         const form = new Form(OptHandler.form(formObj));
-        dbhandler.writeForm(form, (err: Error, formResult: Form) => {
+        dbhandler.form.write(form, (err: Error, formResult: Form) => {
             expect(err).to.be.a("null");
             expect(formResult.id).to.be.equal(5);
             let inputId: number = 16;
@@ -494,7 +498,6 @@ describe("Read and Write on Database", () => {
             }
             done();
         });
-
     });
 
     it("should read an existent form Answer", (done) => {
@@ -518,26 +521,29 @@ describe("Read and Write on Database", () => {
             , value: "Answer to Question 3 Form 1"
        };
 
-        const inputAnswerOptionsDict: InputAnswerOptionsDict = {1: [inputAnswersOpt1], 2: [inputAnswersOpt2], 3: [inputAnswersOpt3]};
-        const data: Date = new Date("2019-02-21 12:10:25");
-        dbhandler.readForm(1, (error: Error, form: Form) => {
+        const inputAnswerOptionsDict: InputAnswerOptionsDict = {
+            1: [inputAnswersOpt1]
+            , 2: [inputAnswersOpt2]
+            , 3: [inputAnswersOpt3]
+        };
+
+        const date: Date = new Date("2019-02-21 12:10:25");
+        dbhandler.form.read(1, (error: Error, form: Form) => {
             const formAnswerOptions: FormAnswerOptions = {
                id: 3
                , form
-               , timestamp: data
+               , timestamp: date
                , inputsAnswerOptions: inputAnswerOptionsDict
-           };
-            dbhandler.readFormAnswer(3, (err: Error, formAnswer: FormAnswer) => {
-               TestHandler.testFormAnswer(formAnswer, new FormAnswer(OptHandler.formAnswer(formAnswerOptions)));
-               done();
-
+            };
+            dbhandler.answer.read(3, (err: Error, formAnswer: FormAnswer) => {
+                TestHandler.testFormAnswer(formAnswer, new FormAnswer(formAnswerOptions));
+                done();
            });
         });
-
     });
 
     it("should read a non existent form Answer", (done) => {
-        dbhandler.readFormAnswer(25, (err: Error, formAnswer: FormAnswer) => {
+        dbhandler.answer.read(25, (err: Error, formAnswer: FormAnswer) => {
             expect(err).to.not.equal(null);
             expect(formAnswer).to.be.undefined;
 
@@ -553,46 +559,52 @@ describe("Read and Write on Database", () => {
             , idInput: 1
             , placement: 0
             , value: "Answer to Question 1 Form 1"
-       };
+        };
+
         const inputAnswersOpt2: InputAnswerOptions  = {
             id: 6
             , idInput: 2
             , placement: 0
             , value: "Answer to Question 2 Form 1"
-       };
+        };
+
         const inputAnswersOpt3: InputAnswerOptions  = {
             id: 7
             , idInput: 3
             , placement: 0
             , value: "Answer to Question 3 Form 1"
-       };
-        const inputAnswerOptionsDict: InputAnswerOptionsDict = {1: [inputAnswersOpt1], 2: [inputAnswersOpt2], 3: [inputAnswersOpt3]};
-        const data: Date = new Date(2019, 6, 4);
-        dbhandler.readForm(1, (error: Error, form: Form) => {
-           const formAnswerOptions: FormAnswerOptions = {
-               form
-               , timestamp: data
-               , inputsAnswerOptions: inputAnswerOptionsDict
-           };
-           const formAnswer = new FormAnswer(OptHandler.formAnswer(formAnswerOptions));
-
-           dbhandler.writeFormAnswer(formAnswer, (err: Error, formAnswerResult: FormAnswer) => {
-               expect(err).to.be.a("null");
-               expect(formAnswerResult.id).to.be.equal(8);
-               let inputAnswerId: number = 18;
-               for (const key of Object.keys(formAnswerResult.inputAnswers)){
-                   for (const inputAnswer of formAnswerResult.inputAnswers[parseInt(key, 10)]){
-                       expect(inputAnswer.id).to.be.equal(inputAnswerId);
-                       inputAnswerId++;
-                   }
-
-               }
-               done();
-           });
-       });
+        };
+
+        const inputAnswerOptionsDict: InputAnswerOptionsDict = {
+            1: [inputAnswersOpt1]
+            , 2: [inputAnswersOpt2]
+            , 3: [inputAnswersOpt3]
+        };
+
+        dbhandler.form.read(1, (error: Error, form: Form) => {
+            const formAnswerOptions: FormAnswerOptions = {
+                form
+                , timestamp: new Date()
+                , inputsAnswerOptions: inputAnswerOptionsDict
+            };
+            const formAnswerObj = new FormAnswer(formAnswerOptions);
+
+            dbhandler.answer.write(formAnswerObj, (err: Error, formAnswerResult: FormAnswer) => {
+                expect(err).to.be.a("null");
+                expect(formAnswerResult.id).to.be.equal(8);
+                let inputAnswerId: number = 18;
+                for (const key of Object.keys(formAnswerResult.inputAnswers)){
+                    for (const inputAnswer of formAnswerResult.inputAnswers[parseInt(key, 10)]){
+                        expect(inputAnswer.id).to.be.equal(inputAnswerId);
+                        inputAnswerId++;
+                    }
+                }
+                done();
+            });
+        });
     });
 
-    it("should insert an formUpdate", (done) => {
+    it("should update a form and insert FormUpdate", (done) => {
         const inputObj1: InputOptions = {
             placement: 0
             , description: "Description Question 1 Form 1"
@@ -654,11 +666,11 @@ describe("Read and Write on Database", () => {
                 , inputObj3
             ]
         };
-        const dateTMP: Date = new Date();
         const formUpdateObj: FormUpdateOptions = {
             id: 1
             , form: formObj
-            , updateDate: dateTMP
+            , updateDate: new Date()
+            , changed: true
             , inputUpdates: [
                 updateObj1
                 , updateObj2
@@ -666,10 +678,168 @@ describe("Read and Write on Database", () => {
             ]
         };
 
-        let formUpdateTmp: FormUpdate;
+        dbhandler.form.update(new FormUpdate (formUpdateObj), (err: Error) => {
+            expect(err).to.be.a("null");
+            done();
+        });
+    });
+
+    it("should update inputs and insert FormUpdate", (done) => {
+        const inputObj1: InputOptions = {
+            placement: 0
+            , description: "Description Question 1 Form 1"
+            , question: "Question 1 Form 1"
+            , type: InputType.TEXT
+            , validation: []
+            , id: 1
+        };
+        const updateObj1: InputUpdateOptions = {
+            id: 1
+            , input: inputObj1
+            , inputOperation: UpdateType.REMOVE
+            , value: null
+        };
+
+        const inputObj2: InputOptions = {
+            placement: 1
+            , description: "Description Question 2 Form 1"
+            , question:  "Question 2 Form 1"
+            , type: InputType.TEXT
+            , validation: [
+                { type: ValidationType.MAXCHAR, arguments: ["10"] }
+                , { type: ValidationType.MINCHAR, arguments: ["2"] }
+            ]
+            , id: 3
+        };
+        const updateObj2: InputUpdateOptions = {
+            id: 2
+            , input: inputObj2
+            , inputOperation: UpdateType.REMOVE
+            , value: null
+        };
+
+        const inputObj3: InputOptions = {
+            placement: 2
+            , description: "Description Question 3 Form 1"
+            , question: "Question 3 Form 1"
+            , type: InputType.TEXT
+            , validation: [
+                { type: ValidationType.REGEX, arguments: ["\\d{5}-\\d{3}"] }
+                , { type: ValidationType.MANDATORY, arguments: [] }
+            ]
+            , id: 2
+        };
+        const updateObj3: InputUpdateOptions = {
+            id: 3
+            , input: inputObj3
+            , inputOperation: UpdateType.REMOVE
+            , value: null
+        };
 
-        formUpdateTmp = new FormUpdate(formUpdateObj);
-        dbhandler.updateForm(formUpdateTmp, (err: Error) => {
+        const formObj: FormOptions = {
+            id: 1
+            , title: "Form Title 1"
+            , description: "Form Description 1"
+            , inputs: [
+                inputObj1
+                , inputObj2
+                , inputObj3
+            ]
+        };
+        const formUpdateObj: FormUpdateOptions = {
+            id: 1
+            , form: formObj
+            , updateDate: new Date()
+            , changed: false
+            , inputUpdates: [
+                updateObj1
+                , updateObj2
+                , updateObj3
+            ]
+        };
+
+        dbhandler.form.update(new FormUpdate (formUpdateObj), (err: Error) => {
+            expect(err).to.be.a("null");
+            done();
+        });
+    });
+
+    it("should reenabled inputs and insert FormUpdate", (done) => {
+        const inputObj1: InputOptions = {
+            placement: 0
+            , description: "Description Question 1 Form 1"
+            , question: "Question 1 Form 1"
+            , type: InputType.TEXT
+            , validation: []
+            , id: 1
+        };
+        const updateObj1: InputUpdateOptions = {
+            id: 1
+            , input: inputObj1
+            , inputOperation: UpdateType.REENABLED
+            , value: null
+        };
+
+        const inputObj2: InputOptions = {
+            placement: 1
+
+            , description: "Description Question 2 Form 1"
+            , question:  "Question 2 Form 1"
+            , type: InputType.TEXT
+            , validation: [
+                { type: ValidationType.MAXCHAR, arguments: ["10"] }
+                , { type: ValidationType.MINCHAR, arguments: ["2"] }
+            ]
+            , id: 3
+        };
+        const updateObj2: InputUpdateOptions = {
+            id: 2
+            , input: inputObj2
+            , inputOperation: UpdateType.REENABLED
+            , value: null
+        };
+
+        const inputObj3: InputOptions = {
+            placement: 2
+            , description: "Description Question 3 Form 1"
+            , question: "Question 3 Form 1"
+            , type: InputType.TEXT
+            , validation: [
+                { type: ValidationType.REGEX, arguments: ["\\d{5}-\\d{3}"] }
+                , { type: ValidationType.MANDATORY, arguments: [] }
+            ]
+            , id: 2
+        };
+        const updateObj3: InputUpdateOptions = {
+            id: 3
+            , input: inputObj3
+            , inputOperation: UpdateType.REENABLED
+            , value: null
+        };
+
+        const formObj: FormOptions = {
+            id: 1
+            , title: "Form Title 1"
+            , description: "Form Description 1"
+            , inputs: [
+                inputObj1
+                , inputObj2
+                , inputObj3
+            ]
+        };
+        const formUpdateObj: FormUpdateOptions = {
+            id: 1
+            , form: formObj
+            , updateDate: new Date()
+            , changed: false
+            , inputUpdates: [
+                updateObj1
+                , updateObj2
+                , updateObj3
+            ]
+        };
+
+        dbhandler.form.update(new FormUpdate (formUpdateObj), (err: Error) => {
             expect(err).to.be.a("null");
             done();
         });
@@ -703,9 +873,302 @@ describe("Read and Write on Database", () => {
             , inputUpdates: [ inputUpdateObj ]
         };
 
-        dbhandler.updateDatabase(formUpdateObj, (err: Error) => {
+        dbhandler.form.update(formUpdateObj, (err: Error) => {
             expect(err).to.be.not.a("null");
             done();
         });
     });
+
+    it("should insert a input with answer sugestions", (done) => {
+
+        const inputObj1: Input = {
+            placement: 0
+            , description: "Description Question 1 Form 6"
+            , question: "Question 1 Form 6"
+            , enabled: true
+            , type: InputType.CHECKBOX
+            , sugestions: [
+                { value: "Sugestion 1", placement: 0 }
+                , { value: "Sugestion 2", placement: 1 }
+                , { value: "Sugestion 3", placement: 2 }
+            ]
+            , validation: [
+                { type: ValidationType.SOMECHECKBOX, arguments: [] }
+            ]
+            , id: 18
+        };
+
+        const inputObj2: Input = {
+            placement: 1
+            , description: "Description Question 2 Form 6"
+            , question: "Question 2 Form 6"
+            , enabled: true
+            , type: InputType.RADIO
+            , sugestions: [
+                { value: "Sugestion 4", placement: 0 }
+                , { value: "Sugestion 5", placement: 1 }
+                , { value: "Sugestion 6", placement: 2 }
+            ]
+            , validation: []
+            , id: 19
+        };
+
+        const inputObj3: Input = {
+            placement: 2
+            , description: "Description Question 3 Form 6"
+            , question: "Question 3 Form 6"
+            , enabled: true
+            , type: InputType.SELECT
+            , sugestions: [
+                { value: "Sugestion 1", placement: 0 }
+                , { value: "Sugestion 2", placement: 1 }
+            ]
+            , validation: [
+                { type: ValidationType.DEPENDENCY, arguments: ["19", "1"] }
+                , { type: ValidationType.DEPENDENCY, arguments: ["20", "1"] }
+            ]
+            , id: 20
+        };
+
+        const inputObj4: Input = {
+            placement: 3
+            , description: "Description Question 4 Form 6"
+            , question: "Question 4 Form 6"
+            , enabled: true
+            , type: InputType.CHECKBOX
+            , sugestions: [
+                { value: "Sugestion n", placement: 0 }
+                , { value: "Sugestion n+1", placement: 1 }
+                , { value: "Sugestion n+2", placement: 2 }
+                , { value: "Sugestion n+3", placement: 4 }
+            ]
+            , validation: [
+                { type: ValidationType.SOMECHECKBOX, arguments: [] }
+            ]
+            , id: 21
+        };
+
+        const inputObj5: Input = {
+            placement: 4
+            , description: "Description Question 5 Form 6"
+            , question: "Question 5 Form 6"
+            , enabled: true
+            , type: InputType.TEXT
+            , sugestions: []
+            , validation: [
+                { type: ValidationType.DEPENDENCY, arguments: ["18", "2"] }
+            ]
+            , id: 22
+        };
+
+        const formObj: Form = {
+            title: "Form Title 6"
+            , description: "Form Description 6"
+            , inputs: [
+                inputObj1
+                , inputObj2
+                , inputObj3
+                , inputObj4
+                , inputObj5
+            ]
+            , id: 6
+        };
+
+        dbhandler.form.write(formObj, (err: Error, formResult: Form) => {
+            expect(err).to.be.a("null");
+            TestHandler.testForm(formObj, formResult);
+            done();
+        });
+    });
+
+    it("should insert a form with typeof validation", (done) => {
+
+        const inputObj1: Input = {
+            placement: 0
+            , description: "Description Question 1 Form 7"
+            , question: "Question 1 form 7"
+            , enabled: true
+            , type: InputType.TEXT
+            , sugestions: []
+            , validation: [
+                { type: ValidationType.TYPEOF, arguments: ["int"] }
+                , { type: ValidationType.MAXANSWERS, arguments: ["2"] }
+            ]
+            , id: 23
+        };
+
+        const inputObj2: Input = {
+            placement: 1
+            , description: "Description Question 2 Form 7"
+            , question: "Question 2 form 7"
+            , enabled: true
+            , type: InputType.TEXT
+            , sugestions: []
+            , validation: [
+                { type: ValidationType.TYPEOF, arguments: ["int"] }
+                , { type: ValidationType.MAXANSWERS, arguments: ["1"] }
+            ]
+            , id: 24
+        };
+
+        const inputObj3: Input = {
+            placement: 2
+            , description: "Description Question 3 Form 7"
+            , question: "Question 3 form 7"
+            , enabled: true
+            , type: InputType.TEXT
+            , sugestions: []
+            , validation: [
+                { type: ValidationType.TYPEOF, arguments: ["float"] }
+            ]
+            , id: 25
+        };
+
+        const inputObj4: Input = {
+            placement: 3
+            , description: "Description Question 4 Form 7"
+            , question: "Question 4 form 7"
+            , enabled: true
+            , type: InputType.TEXT
+            , sugestions: []
+            , validation: [
+                { type: ValidationType.TYPEOF, arguments: ["float"] }
+            ]
+            , id: 26
+        };
+
+        const inputObj5: Input = {
+            placement: 4
+            , description: "Description Question 1 Form 8"
+            , question: "Question 1 form 8"
+            , enabled: true
+            , type: InputType.TEXT
+            , sugestions: []
+            , validation: [
+                { type: ValidationType.TYPEOF, arguments: ["date"] }
+                , { type: ValidationType.MAXANSWERS, arguments: ["2"] }
+            ]
+            , id: 27
+        };
+
+        const inputObj6: Input = {
+            placement: 5
+            , description: "Description Question 2 Form 8"
+            , question: "Question 2 form 8"
+            , enabled: true
+            , type: InputType.TEXT
+            , sugestions: []
+            , validation: [
+                { type: ValidationType.TYPEOF, arguments: ["date"] }
+            ]
+            , id: 28
+        };
+
+        const inputObj7: Input = {
+            placement: 6
+            , description: "Description Question 3 Form 8"
+            , question: "Question 3 form 8"
+            , enabled: true
+            , type: InputType.TEXT
+            , sugestions: []
+            , validation: [
+                { type: ValidationType.TYPEOF, arguments: ["invalid"] }
+                , { type: ValidationType.MAXANSWERS, arguments: ["invalid"] }
+                , { type: ValidationType.DEPENDENCY, arguments: ["28", "invalid"] }
+            ]
+            , id: 29
+        };
+
+        const formObj: Form = {
+            title: "Form Title 7"
+            , description: "Form Description 7"
+            , inputs: [
+                inputObj1
+                , inputObj2
+                , inputObj3
+                , inputObj4
+                , inputObj5
+                , inputObj6
+                , inputObj7
+            ]
+            , id: 7
+        };
+
+        dbhandler.form.write(formObj, (err: Error, formResult: Form) => {
+            expect(err).to.be.a("null");
+            TestHandler.testForm(formObj, formResult);
+            done();
+        });
+    });
+
+    it("should insert form answer validation somecheckbox", (done) => {
+
+        const inputAnswersOpt1: InputAnswerOptions  = {
+            id: undefined
+            , idInput: 18
+            , placement: 0
+            , value: "true"
+        };
+
+        const inputAnswersOpt2: InputAnswerOptions  = {
+            id: undefined
+            , idInput: 18
+            , placement: 1
+            , value: "true"
+        };
+
+        const inputAnswersOpt3: InputAnswerOptions  = {
+            id: undefined
+            , idInput: 18
+            , placement: 2
+            , value: "false"
+        };
+
+        const inputAnswersOpt4: InputAnswerOptions  = {
+            id: undefined
+            , idInput: 19
+            , placement: 1
+            , value: "true"
+        };
+
+        const inputAnswersOpt5: InputAnswerOptions  = {
+            id: undefined
+            , idInput: 20
+            , placement: 1
+            , value: "true"
+        };
+
+        const inputAnswerOptionsDict: InputAnswerOptionsDict = {
+            18: [
+                inputAnswersOpt1
+                , inputAnswersOpt2
+                , inputAnswersOpt3
+            ]
+            , 19: [inputAnswersOpt4]
+            , 20: [inputAnswersOpt5]
+            , 21: []
+        };
+
+        dbhandler.form.read(6, (error: Error, form: Form) => {
+            const formAnswerOptions: FormAnswerOptions = {
+                form
+                , timestamp: new Date()
+                , inputsAnswerOptions: inputAnswerOptionsDict
+            };
+            const formAnswerObj = new FormAnswer(formAnswerOptions);
+
+            dbhandler.answer.write(formAnswerObj, (err: Error, formAnswerResult: FormAnswer) => {
+                expect(err).to.be.a("null");
+                expect(formAnswerResult.id).to.be.equal(9);
+                let inputAnswerId: number = 21;
+                for (const key of Object.keys(formAnswerResult.inputAnswers)){
+                    for (const inputAnswer of formAnswerResult.inputAnswers[parseInt(key, 10)]){
+                        expect(inputAnswer.id).to.be.equal(inputAnswerId);
+                        inputAnswerId++;
+                    }
+                }
+                done();
+            });
+        });
+    });
 });
diff --git a/src/utils/dbHandler.ts b/src/utils/dbHandler.ts
index b7b06542be5bedee40930b1a9ce0801d6654785c..6d8217870080a22745d8902a0cee01417c090968 100644
--- a/src/utils/dbHandler.ts
+++ b/src/utils/dbHandler.ts
@@ -19,928 +19,31 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-import { eachOfSeries, eachSeries, map, seq, waterfall } from "async";
 import { Pool, PoolConfig, QueryResult } from "pg";
-import { Form, FormOptions } from "../core/form";
-import { FormAnswer, FormAnswerOptions } from "../core/formAnswer";
-import { FormUpdate, FormUpdateOptions } from "../core/formUpdate";
-import { Input, InputOptions, Validation } from "../core/input";
-import { InputAnswer, InputAnswerDict, InputAnswerOptions, InputAnswerOptionsDict } from "../core/inputAnswer";
-import { InputUpdate, InputUpdateOptions } from "../core/inputUpdate";
-import { EnumHandler, InputType, UpdateType, ValidationType } from "./enumHandler";
-import { ErrorHandler} from "./errorHandler";
-import { OptHandler } from "./optHandler";
-import { Sorter } from "./sorter";
+import { AnswerQueryBuilder } from "./answerQueryBuilder";
+import { configs } from "./config";
+import { FormQueryBuilder } from "./formQueryBuilder";
 
-/** Parameters used to create a parametrized query, to avoid SQL injection */
-export interface QueryOptions {
-    /** query string to execute */
-    query: string;
-
-    /** Array of input. containing question */
-    parameters: any[];
-}
 /**
  * Class of the SGBD from the Form Creator Api perspective. Used to
  * perform all the operations into the database that the Form Creator Api
- * requires. This operations include read and write data.
+ * requires.
  */
-
 export class DbHandler {
 
+    /** Object used to control Form operations. */
+    public readonly form: FormQueryBuilder;
+    /** Object used to control FormAnswer operations. */
+    public readonly answer: AnswerQueryBuilder;
     /** Information used to connect with a PostgreSQL database. */
     private pool: Pool;
 
     /**
      * Creates a new adapter with the database connection configuration.
-     * @param config - The information required to create a connection with
-     * the database.
      */
     constructor(config: PoolConfig) {
         this.pool = new Pool(config);
+        this.form = new FormQueryBuilder(this.pool);
+        this.answer = new AnswerQueryBuilder(this.form, this.pool);
     }
-
-    /**
-     * Asynchronously executes a query and get its result.
-     * @param query - Query (SQL format) to be executed.
-     * @param cb - Callback function which contains the data read.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.result - Query result.
-     */
-
-    public executeQuery(query: QueryOptions , cb: (err: Error, result?: QueryResult) =>  void): void{
-
-        this.pool.connect((err, client, done) => {
-
-            if (err) {
-                cb(err);
-                return;
-            }
-
-            client.query(query.query, query.parameters, (error, result) => {
-            // call 'done()' to release client back to pool
-                done();
-                cb(error, (result) ? result : null);
-            });
-        });
-    }
-
-    /**
-     * Asynchronously ends a transaction
-     */
-    public commit(cb: (err: Error, result?: QueryResult) =>  void){
-        this.executeQuery({query: "COMMIT;", parameters: []}, cb);
-    }
-    /**
-     * Asynchronously rollback a transaction
-     */
-    public rollback(cb: (err: Error, result?: QueryResult) =>  void){
-        this.executeQuery({query: "ROLLBACK;", parameters: []}, cb);
-    }
-
-    /**
-     * Asynchronously starts a transaction
-     */
-    public begin(cb: (err: Error, result?: QueryResult) =>  void){
-        this.executeQuery({query: "BEGIN;", parameters: []}, cb);
-    }
-
-    /**
-     * Asynchronously list all forms in database.
-     * @param cb - Callback function which contains the data read.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.form - list of form or a empty list if there is no form on database.
-     */
-    public listForms(cb: (err: Error, forms?: Form[]) =>  void){
-        const query: QueryOptions = {query: "SELECT id, title, description FROM form;", parameters: []};
-        const forms: Form[] = [];
-
-        this.executeQuery(query, (err: Error, result?: QueryResult) => {
-            if (err) {
-                cb(err);
-                return;
-            }
-
-            for (const row of result.rows){
-                const formObj: FormOptions = {
-                    id: row["id"]
-                    , title: row["title"]
-                    , description: row["description"]
-                    , inputs: []
-                };
-                let formTmp: Form;
-                try{
-                    formTmp = new Form ( OptHandler.form(formObj));
-                }
-                catch (e){
-                    cb(e);
-                    return;
-                }
-
-                forms.push(formTmp);
-            }
-            cb(err, forms);
-        });
-    }
-
-    /**
-     * Asynchronously executes a query and get a Form.
-     * @param id - Form identifier to be founded.
-     * @param cb - Callback function which contains the data read.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.form - Form or null if form not exists.
-     */
-    public readForm(id: number, cb: (err: Error, form?: Form) =>  void){
-
-        const queryString: string = "SELECT id, title, description FROM form WHERE id=$1;";
-        const query: QueryOptions = {query: queryString, parameters: [id]};
-
-        waterfall([
-            (callback: (err: Error, result?: QueryResult) =>  void) => {
-                this.begin(callback);
-            },
-            (result: QueryResult, callback: (err: Error, result?: QueryResult) =>  void) => {
-                this.executeQuery(query, callback);
-            },
-            (result: QueryResult, callback: (err: Error, form?: Form) =>  void) => {
-
-                if (result.rowCount !== 1){
-                    callback(ErrorHandler.badIdAmount(result.rowCount));
-                    return;
-                }
-                this.readInputWithFormId(id, (error: Error, inputsResult: Input[]) => {
-                    const formObj: FormOptions = {
-                        id: result.rows[0]["id"]
-                        , title: result.rows[0]["title"]
-                        , description: result.rows[0]["description"]
-                        , inputs: inputsResult
-                    };
-                    let formTmp: Form;
-
-                    try{
-                        formTmp = new Form ( OptHandler.form(formObj));
-                    }
-                    catch (e){
-                        callback(e);
-                        return;
-                    }
-
-                    callback(error, formTmp);
-                });
-            },
-            (form: Form, callback: (err: Error, form?: Form) =>  void) => {
-
-                this.commit((error: Error, result?: QueryResult) => {
-                    callback(error, form);
-                });
-            }
-        ], (err, result: Form) => {
-
-            if (err){
-                this.rollback( (error: Error, results?: QueryResult) => {
-                    cb(err);
-                    return;
-                });
-                return;
-            }
-            cb(err, result);
-
-        });
-
-    }
-
-    /**
-     * A private method to asynchronously executes a query and get a list of Inputs.
-     * @param id - Form identifier which inputs are linked to.
-     * @param cb - Callback function which contains the data read.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.inputs - Input array or an empty list if there is no input linked to form.
-     */
-    private readInputWithFormId(id: number, cb: (err: Error, inputs?: InputOptions[]) =>  void){
-        const queryString: string = "SELECT id, placement, input_type, question, description FROM input WHERE id_form=$1 and enabled=true;";
-        const query: QueryOptions = {query: queryString, parameters: [id]};
-
-        this.executeQuery(query, (err: Error, result?: QueryResult) => {
-            map(result.rows, (innerResult, callback) => {
-                this.readInputValidationWithInputId(innerResult["id"], (error: Error, validationResult: Validation[]) => {
-                    const inputObj: InputOptions = {
-                        id: innerResult["id"]
-                        , placement: innerResult["placement"]
-                        , description: innerResult["description"]
-                        , question: innerResult["question"]
-                        , validation: validationResult
-                        , type: EnumHandler.parseInputType(innerResult["input_type"])
-                    };
-                    let inputTmp: InputOptions;
-                    try{
-                        inputTmp = OptHandler.input(inputObj);
-                    }
-                    catch (e){
-                        callback(e);
-                        return;
-                    }
-
-                    callback(error, inputTmp);
-                });
-            }, (errors, inputs: InputOptions[]) => {
-
-                if (errors){
-                    this.rollback( (error: Error, results?: QueryResult) => {
-                        cb(errors);
-                        return;
-                    });
-                    return;
-                }
-
-                const sortedInputs: InputOptions[] = Sorter.sortByPlacement(inputs);
-
-                cb(errors, sortedInputs);
-            });
-        });
-    }
-
-    /**
-     * A private method to asynchronously executes a query and get a list of Validations based on a Input id.
-     * @param id - Input identifier which validations are linked to.
-     * @param cb - Callback function which contains the data read.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.validations - Validation array or an empty list if there is no validation for selected input.
-     */
-    private readInputValidationWithInputId(id: number, cb: (err: Error, validations?: Validation[]) =>  void){
-        const queryString: string = "SELECT id, validation_type FROM input_validation WHERE id_input=$1;";
-        const query: QueryOptions = {
-            query: queryString
-            , parameters: [id]
-        };
-
-        this.executeQuery(query, (err: Error, result?: QueryResult) => {
-            map(result.rows, (innerResult, callback) => {
-                this.readInputValidationArgumentWithInputValidationId(innerResult["id"], (error, argumentsArray) => {
-                    const validationTmp: Validation = {
-                        type:  EnumHandler.parseValidationType(innerResult["validation_type"]),
-                        arguments: argumentsArray
-                    };
-                    callback(error, validationTmp);
-                });
-            }, (errors, validation: Validation[]) => {
-                cb(errors, validation);
-            });
-        });
-
-    }
-
-    /**
-     * A private method to asynchronously executes a query and get a list of Validation Argument based on a Validation id.
-     * @param id - Validation identifier which Validation Arguments are linked to.
-     * @param cb - Callback function which contains the data read.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.argumentsArray - Validation Arguments array or an empty list if there is no validation argument for selected input.
-     */
-    private readInputValidationArgumentWithInputValidationId(id: number, cb: (err: Error, argumentsArray?: any[]) =>  void){
-        const queryString: string = "SELECT id, argument, placement FROM \
-input_validation_argument WHERE \
-id_input_validation=$1;";
-        const query: QueryOptions = {
-            query: queryString
-            , parameters: [id]
-        };
-
-        // cb(null);
-
-        this.executeQuery(query, (error: Error, result?: QueryResult) => {
-
-            const sortedResult: any[] = Sorter.sortByPlacement(result.rows);
-            const argumentArrayTmp = [];
-            for (const innerResult of sortedResult){
-                argumentArrayTmp.push(innerResult["argument"]);
-            }
-
-            cb(error, argumentArrayTmp);
-        });
-
-    }
-
-    /**
-     * Asynchronously insert a form on Database and return it.
-     * @param form - Form to be inserted.
-     * @param cb - Callback function which contains the inserted data.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.formResult - Form or null if form any error occurs.
-     */
-
-    public writeForm(form: Form, cb: (err: Error, formResult?: Form) =>  void){
-        const queryString: string = "INSERT INTO form (title, description) VALUES( $1, $2 ) RETURNING id;";
-        const query: QueryOptions = {
-            query: queryString
-            , parameters: [
-                form.title
-                , form.description
-            ]
-        };
-
-        waterfall([
-            (callback: (err: Error, result?: QueryResult) =>  void) => {
-                this.begin(callback);
-            },
-            (result: QueryResult, callback: (err: Error, result?: QueryResult) =>  void) => {
-                this.executeQuery(query, callback);
-            },
-            (result: QueryResult, callback: (err: Error, formId?: number) =>  void) => {
-                if (result.rowCount !== 1){
-                    callback(ErrorHandler.notInserted("Form"));
-                    return;
-                }
-                eachSeries(form.inputs, (input: Input, innerCallback) => {
-                    this.writeInputWithFormId(result.rows[0]["id"], input, innerCallback);
-                }, (error) => {
-                    if (error){
-                        callback(error);
-                        return;
-
-                    }
-                    callback(error, result.rows[0]["id"]);
-
-                });
-            },
-            (formId: number, callback: (err: Error, formId?: number) =>  void) => {
-
-                this.commit((error: Error, result?: QueryResult) => {
-                    callback(error, formId);
-                });
-            },
-            (formId: number, callback: (err: Error, formResult?: Form) =>  void) => {
-
-                this.readForm(formId, callback);
-
-            }
-        ], (err, result: Form) => {
-
-            if (err){
-                this.rollback( (error: Error, results?: QueryResult) => {
-                    cb(err);
-                    return;
-                });
-                return;
-            }
-            cb(err, result);
-
-        });
-    }
-
-    /**
-     * Asynchronously insert a Input on Database and return it.
-     * @param formId - Form identifier to relate with Input.
-     * @param input - Input to be inserted.
-     * @param cb - Callback function.
-     * @param cb.err - Error information when the method fails.
-     */
-    private writeInputWithFormId(formId: number, input: Input, cb: (err: Error, result?: number) =>  void){
-        const queryString: string = "INSERT INTO input (\
-id_form, placement, input_type, enabled, question, description)\
-VALUES ( $1, $2, $3, $4, $5, $6) RETURNING id;";
-
-        const query: QueryOptions = {
-            query: queryString
-            , parameters: [
-                formId
-                , input.placement
-                , EnumHandler.stringifyInputType(input.type)
-                , true
-                , input.question
-                , input.description
-            ]
-        };
-
-        this.executeQuery(query, (err: Error, result?: QueryResult) => {
-            if (err){
-                cb(err);
-                return;
-            }
-
-            if (result.rowCount !== 1){
-                cb(ErrorHandler.notInserted("Input"));
-                return;
-            }
-
-            eachSeries(input.validation, (validation: Validation, callback) => {
-
-                this.writeValidationWithInputId(result.rows[0]["id"], validation, callback);
-
-            }, (error) => {
-
-                cb(error, result.rows[0]["id"]);
-
-            });
-        });
-
-    }
-    /**
-     * Asynchronously insert a Validation on Database and return it.
-     * @param inputId - Input id to relate with Validation.
-     * @param validation - Validation to be inserted.
-     * @param cb - Callback function.
-     * @param cb.err - Error information when the method fails.
-     */
-    private writeValidationWithInputId(inputId: number, validation: Validation, cb: (err: Error) =>  void){
-
-        const queryString: string = "INSERT INTO input_validation\
-( id_input, validation_type) VALUES\
-( $1, $2 ) RETURNING id;";
-
-        const query: QueryOptions = {
-            query: queryString
-            , parameters: [
-                inputId
-                , EnumHandler.stringifyValidationType(validation.type)
-            ]
-        };
-
-        this.executeQuery(query, (err: Error, result?: QueryResult) => {
-
-            if (err){
-                cb(err);
-                return;
-            }
-
-            if (result.rowCount !== 1){
-                cb(ErrorHandler.notInserted("Validation"));
-                return;
-            }
-
-            eachOfSeries(validation.arguments, (argument, placement: number, callback) => {
-
-                this.writeValidationArgumentWithInputIdAndPlacement(result.rows[0]["id"], argument, placement, callback);
-            }, (error) => {
-                cb(error);
-            });
-
-        });
-
-    }
-
-    /**
-     * Asynchronously insert a Validation Argument on Database and return it.
-     * @param validationId - Validation identifier to relate with Argument.
-     * @param argument - Argument to be inserted.
-     * @param placement - placement where argument should be.
-     * @param cb - Callback function.
-     * @param cb.err - Error information when the method fails.
-     */
-    private writeValidationArgumentWithInputIdAndPlacement(validationId: number, argument: string, placement: number, cb: (err: Error) =>  void){
-
-        const queryString: string = "INSERT INTO input_validation_argument \
-( id_input_validation, argument, placement ) VALUES\
-( $1, $2, $3 ) RETURNING id;";
-
-        const query: QueryOptions = {
-            query: queryString
-            , parameters: [
-                validationId
-                , argument
-                , placement
-            ]
-        };
-
-        this.executeQuery(query, (err: Error, result?: QueryResult) => {
-
-            if (err){
-                cb(err);
-                return;
-            }
-
-            if (result.rowCount !== 1){
-                cb(ErrorHandler.notInserted("Validation Argument"));
-                return;
-            }
-
-            cb(err);
-
-        });
-
-    }
-
-    /**
-     * Asynchronously insert a form answer on Database and return it.
-     * @param formAnswer - FormAnswer to be inserted.
-     * @param cb - Callback function which contains the inserted data.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.formAnswerResult - Form or null if form any error occurs.
-     */
-    public writeFormAnswer(formAnswer: FormAnswer, cb: (err: Error, formAnswerResult?: FormAnswer) =>  void){
-        const queryString: string = "INSERT INTO form_answer (id_form, answered_at) VALUES( $1, $2 ) RETURNING id;";
-        const query: QueryOptions = {
-            query: queryString
-            , parameters: [
-                formAnswer.form.id
-                , formAnswer.timestamp
-            ]
-        };
-
-        waterfall([
-            (callback: (err: Error, result?: QueryResult) =>  void) => {
-                this.begin(callback);
-            },
-            (result: QueryResult, callback: (err: Error, result?: QueryResult) =>  void) => {
-                this.executeQuery(query, callback);
-            },
-            (result: QueryResult, callback: (err: Error, formAnswerId?: number) =>  void) => {
-                if (result.rowCount !== 1){
-                    callback(ErrorHandler.notInserted("FormAnswer"));
-                    return;
-                }
-                // NOTE: Although this two "FOR"s the complexity is O(n)
-                // This first eachSeries iterates over the keys of the dictonary
-                eachSeries(Object.keys(formAnswer.inputAnswers), (key, outerCallback) => {
-                    // this second one iterates over the array of the objects within the current key
-
-                    eachSeries(formAnswer.inputAnswers[parseInt(key, 10)], (inputsAnswer: InputAnswer, innerCallback) => {
-                        this.writeInputAnswerWithFormId(result.rows[0]["id"], inputsAnswer, innerCallback);
-                    }, (error) => {
-                        if (error){
-                            outerCallback(error);
-                            return;
-                        }
-                        outerCallback(error);
-                    });
-                }, (error) => {
-                    if (error){
-                        callback(error);
-                        return;
-                    }
-                    callback(error, result.rows[0]["id"]);
-                });
-
-            },
-            (formAnswerId: number, callback: (err: Error, formId?: number) =>  void) => {
-
-                this.commit((error: Error, result?: QueryResult) => {
-                    callback(error, formAnswerId);
-                });
-            },
-            (formAnswerId: number, callback: (err: Error, formResult?: FormAnswer) =>  void) => {
-
-                this.readFormAnswer(formAnswerId, callback);
-
-            }
-        ], (err, result: FormAnswer) => {
-
-            if (err){
-                this.rollback( (error: Error, results?: QueryResult) => {
-                    cb(err);
-                    return;
-                });
-                return;
-            }
-            cb(err, result);
-
-        });
-    }
-
-    /**
-     * Asynchronously insert a Input Answer on Database and return it.
-     * @param formAnswerId - Form Answer identifier to relate with Input Answer.
-     * @param inputsAnswer - InputsAnswer to be inserted.
-     * @param cb - Callback function.
-     * @param cb.err - Error information when the method fails.
-     */
-    private writeInputAnswerWithFormId(formAnswerId: number, inputAnswer: InputAnswer, cb: (err: Error) =>  void){
-        const queryString: string = "INSERT INTO input_answer (\
-id_form_answer, id_input, value, placement)\
-VALUES ( $1, $2, $3, $4) RETURNING id;";
-
-        const query: QueryOptions = {
-            query: queryString
-            , parameters: [
-                formAnswerId
-                , inputAnswer.idInput
-                , inputAnswer.value
-                , inputAnswer.placement
-            ]
-        };
-
-        this.executeQuery(query, (err: Error, result?: QueryResult) => {
-            if (err){
-                cb(err);
-                return;
-            }
-
-            if (result.rowCount !== 1){
-                cb(ErrorHandler.notInserted("InputsAnswer"));
-                return;
-            }
-            cb(err);
-        });
-
-    }
-
-    /**
-     * Asynchronously executes a query and get a Form.
-     * @param id - Form identifier to be founded.
-     * @param cb - Callback function which contains the data read.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.form - Form or null if form not exists.
-     */
-    public readFormAnswer(id: number, cb: (err: Error, formAnswer?: FormAnswer) =>  void){
-
-        const queryString: string = "SELECT id, id_form, answered_at FROM form_answer WHERE id=$1;";
-        const query: QueryOptions = {query: queryString, parameters: [id]};
-
-        waterfall([
-            (callback: (err: Error, result?: QueryResult) =>  void) => {
-                this.begin(callback);
-            },
-            (result: QueryResult, callback: (err: Error, result?: QueryResult) =>  void) => {
-                this.executeQuery(query, callback);
-            },
-            (result: QueryResult, callback: (err: Error, formAnswer?: FormAnswer) =>  void) => {
-                if (result.rowCount !== 1){
-                    callback(ErrorHandler.badIdAmount(result.rowCount));
-                    return;
-                }
-
-                this.readForm(result.rows[0]["id_form"], (err: Error, formResult: Form) => {
-                    this.readInputAnswerWithFormAnswerId(result.rows[0]["id"], (error: Error, inputsAnswerOptionsResult: InputAnswerOptionsDict) => {
-                        const formAnswerOpt: FormAnswerOptions = {
-                            id: result.rows[0]["id"]
-                            , form: formResult
-                            , inputsAnswerOptions: inputsAnswerOptionsResult
-                            , timestamp : result.rows[0]["answered_at"]
-                        };
-                        let formAnswerTmp: FormAnswer;
-
-                        try{
-                            formAnswerTmp = new FormAnswer ( OptHandler.formAnswer(formAnswerOpt));
-                        }
-                        catch (e){
-                            callback(e);
-                            return;
-                        }
-
-                        callback(error, formAnswerTmp);
-                    });
-                });
-            },
-            (formAnswer: FormAnswer, callback: (err: Error, formAnswer?: FormAnswer) =>  void) => {
-
-                this.commit((error: Error, result?: QueryResult) => {
-                    callback(error, formAnswer);
-                });
-            }
-        ], (err, result: FormAnswer) => {
-
-            if (err){
-                this.rollback( (error: Error, results?: QueryResult) => {
-                    cb(err);
-                    return;
-                });
-                return;
-            }
-            cb(err, result);
-
-        });
-
-    }
-
-    /**
-     * A private method to asynchronously executes a query and get a list of Inputs.
-     * @param id - Form identifier which inputs are linked to.
-     * @param cb - Callback function which contains the data read.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.inputs - Input array or an empty list if there is no input linked to form.
-     */
-    private readInputAnswerWithFormAnswerId(id: number, cb: (err: Error, inputsAnswerResult?: InputAnswerOptionsDict) =>  void){
-        const queryString: string = "SELECT id, id_form_answer, id_input, value,\
-placement FROM input_answer WHERE id_form_answer=$1;";
-        const query: QueryOptions = {query: queryString, parameters: [id]};
-
-        this.executeQuery(query, (err: Error, result?: QueryResult) => {
-
-            const inputAnswersOpts: InputAnswerOptions[] = result.rows.map( (inputsAnswerResult) => {
-                const inputAnswersOpt: InputAnswerOptions = {
-                    id: inputsAnswerResult["id"]
-                    , idInput: inputsAnswerResult["id_input"]
-                    , value: inputsAnswerResult["value"]
-                    , placement: inputsAnswerResult["placement"]
-                };
-                return OptHandler.inputAnswer(inputAnswersOpt);
-            });
-
-            const inputsAnswerResults: InputAnswerOptionsDict = {};
-            for (const i of inputAnswersOpts){
-                // FIXME:  There is no coverage teste for this "IF"
-                // it happens because, until this date (04/Jun/2019) I did not implement multivalored inputs
-                // I hope someday someone implements it
-                if (  inputsAnswerResults[i["idInput"]] ) {
-                    inputsAnswerResults[i["idInput"]].push(i);
-                    inputsAnswerResults[i["idInput"]] = Sorter.sortByPlacement(inputsAnswerResults[i["idInput"]]);
-                }else{
-                    inputsAnswerResults[i["idInput"]] = [i];
-                }
-            }
-            cb(err, inputsAnswerResults);
-        });
-    }
-
-    /**
-     * Asynchronously insert a formUpdate and inputUpdates on Database.
-     * @param formUpdate - A FormUpdate with InputUpdates that should be inserted in the database.
-     * @param cb - Callback function.
-     * @param cb.err - Error information when the method fails.
-     */
-    public updateForm(formUpdate: FormUpdate, cb: (err: Error) => void) {
-
-        waterfall([
-            (callback: (err: Error, result?: QueryResult) =>  void) => {
-                this.begin(callback);
-            },
-            (result: QueryResult, callback: (err: Error, result?: number) =>  void) => {
-                this.writeFormUpdate(formUpdate, (err, idFormUpdate: number) => {
-                    if (err) {
-                        callback(err);
-                        return;
-                    }
-                    callback(null, idFormUpdate);
-                });
-            },
-            (idFormUpdate: number, callback: (err: Error) => void) => {
-                eachSeries(formUpdate.inputUpdates, (inputUpdates: InputUpdate, innerCallback) => {
-                    this.writeInputUpdate(idFormUpdate, inputUpdates, innerCallback);
-                }, (error) => {
-                    callback(error);
-                });
-            },
-            (callback: (err: Error) =>  void) => {
-                this.commit((error: Error, result?: QueryResult) => {
-                    callback(error);
-                });
-            }
-        ], (err) => {
-            if (err){
-                this.rollback( (error: Error, results?: QueryResult) => {
-                    cb(err);
-                    return;
-                });
-                return;
-            }
-            cb(null);
-        });
-
-    }
-
-    /**
-     * A private method that execute a query and insert a FormUpdate in the database
-     * @param formUpdate - Form Update to be inserted.
-     * @param cb - Callback function.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.formUpdateId - The id of the inserted FormUpdate.
-     */
-    private writeFormUpdate(formUpdate: FormUpdate, cb: (err: Error, formUpdateId?: number) => void) {
-
-        const queryString: string = "INSERT INTO form_update (id_form, update_date) \
-                                     VALUES ( $1, $2 ) RETURNING id;";
-        const query: QueryOptions = {
-            query: queryString
-            , parameters: [
-                formUpdate.form.id
-                , formUpdate.updateDate
-            ]
-        };
-
-        this.executeQuery(query, (err: Error, result?: QueryResult) => {
-            if (err) {
-                cb(err);
-                return;
-            }
-            cb(err, result.rows[0].id);
-        });
-
-    }
-
-    /**
-     * A private method that execute a query and insert a InputUpdate in the database
-     * @param inputUpdate - Input Update to be inserted.
-     * @param cb - Callback function.
-     * @param cb.err - Error information when the method fails.
-     */
-    private writeInputUpdate(idFormUpdate: number, inputUpdate: InputUpdate, cb: (err: Error) => void) {
-
-        const queryString: string = "INSERT INTO input_update (id_form_update, id_input, input_operation_id, value) \
-                                     VALUES ( $1, $2, $3, $4 );";
-        const query: QueryOptions = {
-            query: queryString
-            , parameters: [
-                idFormUpdate
-                , inputUpdate.input.id
-                , inputUpdate.inputOperation
-                , inputUpdate.value
-            ]
-        };
-
-        this.executeQuery(query, (err: Error, result?: QueryResult) => {
-            cb(err);
-        });
-    }
-
-    /**
-     * A method that update the database based on a given FormUpdate object
-     * @param formUpdate - FormUpdate with the parameters to update the database.
-     * @param cb - Callback function.
-     * @param cb.err - Error information when the method fails.
-     * @param cb.formUpdateResult - A FormUpdate with updated id's.
-     */
-    public updateDatabase(formUpdate: FormUpdate, cb: (err: Error, formUpdateResult?: FormUpdate) => void) {
-
-        const formUpdateResult: FormUpdate = {
-            form: formUpdate.form
-            , updateDate: formUpdate.updateDate
-            , inputUpdates: []
-        };
-
-        eachSeries(formUpdate.inputUpdates, (inputUpdate, callback) => {
-            switch (inputUpdate.inputOperation) {
-                case UpdateType.ADD: {
-                    this.writeInputWithFormId(formUpdate.form.id, inputUpdate.input, (err: Error, id: number) => {
-                        if (err) {
-                            callback(err);
-                        }
-                        const inputOpt: InputOptions = inputUpdate.input;
-                        inputOpt.id = id;
-
-                        const inputUpdateOpt: InputUpdateOptions = {
-                            input: inputOpt
-                            , inputOperation: UpdateType.ADD
-                            , value: null
-                        };
-                        formUpdateResult.inputUpdates.push(new InputUpdate(inputUpdateOpt));
-                        callback(null);
-                    });
-                    break;
-                }
-                case UpdateType.REMOVE: {
-                    // Set enabled option in database as false
-                    this.updateInput(0, inputUpdate.input.id, "enabled", (err: Error) => {
-                        if (err) {
-                            callback(err);
-                        }
-                        formUpdateResult.inputUpdates.push(inputUpdate);
-                        callback(null);
-                    });
-                    break;
-                }
-                case UpdateType.SWAP: {
-                    // Update placement option in database of a input
-                    this.updateInput(inputUpdate.input.placement, inputUpdate.input.id, "placement", (err: Error) => {
-                        if (err) {
-                            callback(err);
-                        }
-                        formUpdateResult.inputUpdates.push(inputUpdate);
-                        callback(null);
-                    });
-                    break;
-                }
-                case UpdateType.REENABLED: {
-                    // Set enabled option in database as true
-                    this.updateInput(1, inputUpdate.input.id, "enabled", (err: Error) => {
-                        if (err) {
-                            callback(err);
-                        }
-                        formUpdateResult.inputUpdates.push(inputUpdate);
-                        callback(null);
-                    });
-                    break;
-                }
-                default: {
-                    callback(new Error ("Operation not recognized"));
-                }
-            }
-        }, (error) => {
-            if (error) {
-                cb(error);
-            }
-            cb(null, formUpdateResult);
-        });
-    }
-
-    /**
-     * A method that execute a query and update a input based on given parameters
-     * @param value - A number to be inserted in the database.
-     * @param id - The input id that should be updated
-     * @param field - The field on database that should be updated.
-     * @param cb - Callback function.
-     * @param cb.err - Error information when the method fails.
-     */
-    private updateInput(value: number, id: number, field: string, cb: (err: Error) => void) {
-        const queryString: string = "UPDATE input SET " + field + " = $1 WHERE id = $2";
-        const query: QueryOptions = {
-            query: queryString
-            , parameters: [
-                value
-                , id
-            ]
-        };
-        this.executeQuery(query, (err: Error, result?: QueryResult) => {
-            cb(err);
-         });
-    }
-
 }
diff --git a/src/utils/diffHandler.spec.ts b/src/utils/diffHandler.spec.ts
index 3867a89b77eb81b4e0df5cfa513ecf1293d38c19..66d4c77b78e7488a3ab51f285e2d57e9e1e1c65e 100644
--- a/src/utils/diffHandler.spec.ts
+++ b/src/utils/diffHandler.spec.ts
@@ -1038,4 +1038,78 @@ describe("Diff Handler", () => {
         done();
     });
 
+    it("should return a valid formUpdate wich changes the title", (done) => {
+        const newInputObj1: Input = {
+            placement: 0
+            , description: "Description Question 1 Form 1"
+            , question: "Question 1 Form 1"
+            , enabled: true
+            , type: InputType.TEXT
+            , validation: []
+            , id: 1
+        };
+        const newInputObj2: Input = {
+            placement: 1
+            , description: "Description Question 2 Form 1"
+            , question:  "Question 2 Form 1"
+            , enabled: true
+            , type: InputType.TEXT
+            , validation: [
+                { type: ValidationType.MAXCHAR, arguments: ["10"] }
+                , { type: ValidationType.MINCHAR, arguments: ["2"] }
+            ]
+            , id: 3
+        };
+        const newFormObj: Form = {
+            id: 1
+            , title: "Title 1"
+            , description: "Description 1"
+            , inputs: [
+                newInputObj1
+                , newInputObj2
+            ]
+        };
+
+        const oldInputObj1: Input = {
+            placement: 0
+            , description: "Description Question 1 Form 1"
+            , question: "Question 1 Form 1"
+            , enabled: true
+            , type: InputType.TEXT
+            , validation: []
+            , id: 1
+        };
+        const oldInputObj2: Input = {
+            placement: 1
+            , description: "Description Question 2 Form 1"
+            , question:  "Question 2 Form 1"
+            , enabled: true
+            , type: InputType.TEXT
+            , validation: [
+                { type: ValidationType.MAXCHAR, arguments: ["10"] }
+                , { type: ValidationType.MINCHAR, arguments: ["2"] }
+            ]
+            , id: 3
+        };
+        const oldFormObj: Form = {
+            id: 1
+            , title: "Form Title 1"
+            , description: "Form Description 1"
+            , inputs: [
+                oldInputObj1
+                , oldInputObj2
+            ]
+        };
+
+        const resFormUpdate = DiffHandler.diff(newFormObj, oldFormObj);
+
+        const expFormUpdate: FormUpdate = {
+            form: newFormObj
+            , updateDate: new Date()
+            , changed: true
+            , inputUpdates: []
+        };
+        TestHandler.testFormUpdate(resFormUpdate, expFormUpdate);
+        done();
+    });
 });
diff --git a/src/utils/diffHandler.ts b/src/utils/diffHandler.ts
index 84cdc704e349b40a76651d9082709790acf7ac88..c033ce7e9ea62656016245657caa9f8b97fa31f4 100644
--- a/src/utils/diffHandler.ts
+++ b/src/utils/diffHandler.ts
@@ -46,6 +46,7 @@ export class DiffHandler {
         const formUpdate: FormUpdate = {
             form: newForm
             , updateDate: new Date()
+            , changed: ((newForm.title !== oldForm.title) || (newForm.description !== oldForm.description))
             , inputUpdates: []
         };
 
diff --git a/src/utils/enumHandler.spec.ts b/src/utils/enumHandler.spec.ts
index dcc32ae289f123bd953a2ecbc09aee9744bb2c7e..b992999db09082db0648ac1b0aa089aa9d7458c3 100644
--- a/src/utils/enumHandler.spec.ts
+++ b/src/utils/enumHandler.spec.ts
@@ -65,21 +65,37 @@ describe("Enum Handler", () => {
 
         const inputNone = EnumHandler.stringifyInputType(InputType.NONE);
         const inputText = EnumHandler.stringifyInputType(InputType.TEXT);
+        const inputRadio = EnumHandler.stringifyInputType(InputType.RADIO);
+        const inputCheckbox = EnumHandler.stringifyInputType(InputType.CHECKBOX);
 
         expect(inputNone).to.be.equal("");
         expect(inputText).to.be.equal("text");
+        expect(inputCheckbox).to.be.equal("checkbox");
+        expect(inputRadio).to.be.equal("radio");
     });
 
     it("should parse string to InputType", () => {
+        const inputNone = EnumHandler.parseInputType("");
         const inputText = EnumHandler.parseInputType("text");
         const inputTextCapitalLetters = EnumHandler.parseInputType("TEXT");
-        const inputNone = EnumHandler.parseInputType("");
+        const inputRadio = EnumHandler.parseInputType("radio");
+        const inputRadioCapitalLetters = EnumHandler.parseInputType("RADIO");
+        const inputCheckbox = EnumHandler.parseInputType("checkbox");
+        const inputCheckboxCapitalLetters = EnumHandler.parseInputType("CHECKBOX");
         const inputFOOL = EnumHandler.parseInputType("fool");
+        const inputSelect = EnumHandler.parseInputType("select");
+        const inputSelectCapitalLetters = EnumHandler.parseInputType("SELECT");
 
         expect(inputText).to.be.equal(InputType.TEXT);
         expect(inputTextCapitalLetters).to.be.equal(InputType.TEXT);
         expect(inputNone).to.be.equal(InputType.NONE);
         expect(inputFOOL).to.be.equal(InputType.NONE);
+        expect(inputCheckbox).to.be.equal(InputType.CHECKBOX);
+        expect(inputCheckboxCapitalLetters).to.be.equal(InputType.CHECKBOX);
+        expect(inputRadio).to.be.equal(InputType.RADIO);
+        expect(inputRadioCapitalLetters).to.be.equal(InputType.RADIO);
+        expect(inputSelect).to.be.equal(InputType.SELECT);
+        expect(inputSelectCapitalLetters).to.be.equal(InputType.SELECT);
     });
 
     it("should stringify ValidationType ", () => {
@@ -88,6 +104,9 @@ describe("Enum Handler", () => {
         const validationMandatory = EnumHandler.stringifyValidationType(ValidationType.MANDATORY);
         const validationMaxChar = EnumHandler.stringifyValidationType(ValidationType.MAXCHAR);
         const validationMinChar = EnumHandler.stringifyValidationType(ValidationType.MINCHAR);
+        const validationTypeOf = EnumHandler.stringifyValidationType(ValidationType.TYPEOF);
+        const validationSomeCheckbox = EnumHandler.stringifyValidationType(ValidationType.SOMECHECKBOX);
+        const validationMaxAnswers = EnumHandler.stringifyValidationType(ValidationType.MAXANSWERS);
         const validationNone = EnumHandler.stringifyValidationType(ValidationType.NONE);
 
         expect(validationNone).to.be.equal("");
@@ -95,6 +114,9 @@ describe("Enum Handler", () => {
         expect(validationMandatory).to.be.equal("mandatory");
         expect(validationMaxChar).to.be.equal("maxchar");
         expect(validationMinChar).to.be.equal("minchar");
+        expect(validationTypeOf).to.be.equal("typeof");
+        expect(validationSomeCheckbox).to.be.equal("somecheckbox");
+        expect(validationMaxAnswers).to.be.equal("maxanswers");
     });
 
     it("should parse string to ValidationType", () => {
@@ -106,6 +128,14 @@ describe("Enum Handler", () => {
         const validationMaxCharyCapitalized = EnumHandler.parseValidationType("MAXCHAR");
         const validationMinChar = EnumHandler.parseValidationType("minchar");
         const validationMinCharyCapitalized = EnumHandler.parseValidationType("MINCHAR");
+        const validationTypeOf = EnumHandler.parseValidationType("typeof");
+        const validationTypeOfCapitalized = EnumHandler.parseValidationType("TYPEOF");
+        const validationSomeCheckbox = EnumHandler.parseValidationType("somecheckbox");
+        const validationSomeCheckboxCapitalized = EnumHandler.parseValidationType("SOMECHECKBOX");
+        const validationMaxAnswers = EnumHandler.parseValidationType("maxanswers");
+        const validationMaxAnswersCapitalized = EnumHandler.parseValidationType("MAXANSWERS");
+        const validationDependency = EnumHandler.parseValidationType("dependency");
+        const validationDependencyCapitalized = EnumHandler.parseValidationType("DEPENDENCY");
         const validationNone = EnumHandler.parseValidationType("");
         const validatioFOOL = EnumHandler.parseValidationType("fool");
 
@@ -117,6 +147,14 @@ describe("Enum Handler", () => {
         expect(validationMaxCharyCapitalized).to.be.equal(ValidationType.MAXCHAR);
         expect(validationMinChar).to.be.equal(ValidationType.MINCHAR);
         expect(validationMinCharyCapitalized).to.be.equal(ValidationType.MINCHAR);
+        expect(validationTypeOf).to.be.equal(ValidationType.TYPEOF);
+        expect(validationTypeOfCapitalized).to.be.equal(ValidationType.TYPEOF);
+        expect(validationSomeCheckbox).to.be.equal(ValidationType.SOMECHECKBOX);
+        expect(validationSomeCheckboxCapitalized).to.be.equal(ValidationType.SOMECHECKBOX);
+        expect(validationMaxAnswers).to.be.equal(ValidationType.MAXANSWERS);
+        expect(validationMaxAnswersCapitalized).to.be.equal(ValidationType.MAXANSWERS);
+        expect(validationDependency).to.be.equal(ValidationType.DEPENDENCY);
+        expect(validationDependencyCapitalized).to.be.equal(ValidationType.DEPENDENCY);
         expect(validationNone).to.be.equal(ValidationType.NONE);
         expect(validatioFOOL).to.be.equal(ValidationType.NONE);
     });
diff --git a/src/utils/enumHandler.ts b/src/utils/enumHandler.ts
index fdc1a2a9a64b93915f6562fc7fe5ab0e6172a35e..b7d2600f797f8a4eb2ae23a2c76d2944faf3bf68 100644
--- a/src/utils/enumHandler.ts
+++ b/src/utils/enumHandler.ts
@@ -17,14 +17,17 @@
  *
  * You should have received a copy of the GNU Affero General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
-*/
+ */
 
 /**
  * Available Input types
  */
 export enum InputType {
-     /** Text type, when input is a text */
+    /** Text type, when input is a text */
     TEXT,
+    CHECKBOX,
+    RADIO,
+    SELECT,
     NONE
 }
 
@@ -37,35 +40,49 @@ export enum UpdateType {
 }
 
 /**
- * Available Validation types
+ * Available Validation types.
  */
 export enum ValidationType {
-     /** Used as error code. No suitable validation found. */
-     NONE,
-     /** Regex type, when input need a regex to validate */
-     REGEX,
-     /** Mandatory type, when input is mandatory */
-     MANDATORY,
-     /** MaxChars type, when input has maximum char limit */
-     MAXCHAR,
-     /** MinChars type, when input has minimum char limit */
-     MINCHAR
+    /** Used as error code. No suitable validation found. */
+    NONE,
+    /** Regex type, when input need a regex to validate. */
+    REGEX,
+    /** Mandatory type, when input is mandatory. */
+    MANDATORY,
+    /** MaxChars type, when input has maximum char limit. */
+    MAXCHAR,
+    /** MinChars type, when input has minimum char limit. */
+    MINCHAR,
+    /** TypeOf type, when input needs to be a certain type. */
+    TYPEOF,
+    /** SomeCheckbox type, when at least one checkbox must be selected. */
+    SOMECHECKBOX,
+    /** MAXANSWERS type, when input has maximum answer limit. */
+    MAXANSWERS,
+    /** DEPENDENCY type, when input depends on another input. */
+    DEPENDENCY
 }
 
 /**
- * Enum's handler. Manage parse through the project.
+ * ENUM's handler. Manage parse through the project.
  */
 export class EnumHandler {
 
     /**
      * Parse an enum(Input type) to string.
      * @param a - Input type to be stringified.
-     * @returns - Input Type as string
+     * @returns - Input Type as string.
      */
     public static stringifyInputType(a: InputType): string {
         switch (a) {
             case InputType.TEXT:
                 return "text";
+            case InputType.CHECKBOX:
+                return "checkbox";
+            case InputType.RADIO:
+                return "radio";
+            case InputType.SELECT:
+                return "select";
             default:
                 return  "";
         }
@@ -81,6 +98,12 @@ export class EnumHandler {
         switch (str) {
             case "text":
                 return InputType.TEXT;
+            case "checkbox":
+                return InputType.CHECKBOX;
+            case "radio":
+                return InputType.RADIO;
+            case "select":
+                return InputType.SELECT;
             default:
                 return InputType.NONE;
         }
@@ -101,6 +124,14 @@ export class EnumHandler {
                 return "maxchar";
             case ValidationType.MINCHAR:
                 return "minchar";
+            case ValidationType.TYPEOF:
+                return "typeof";
+            case ValidationType.SOMECHECKBOX:
+                return "somecheckbox";
+            case ValidationType.MAXANSWERS:
+                return "maxanswers";
+            case ValidationType.DEPENDENCY:
+                return "dependency";
             default:
                 return  "";
         }
@@ -121,6 +152,14 @@ export class EnumHandler {
                 return ValidationType.MAXCHAR;
             case "minchar":
                 return ValidationType.MINCHAR;
+            case "typeof":
+                return ValidationType.TYPEOF;
+            case "somecheckbox":
+                return ValidationType.SOMECHECKBOX;
+            case "maxanswers":
+                return ValidationType.MAXANSWERS;
+            case "dependency":
+                return ValidationType.DEPENDENCY;
             default:
                 return ValidationType.NONE;
         }
diff --git a/src/utils/formQueryBuilder.ts b/src/utils/formQueryBuilder.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8d906b3fdb329a507cd97be12c324ca05797ec09
--- /dev/null
+++ b/src/utils/formQueryBuilder.ts
@@ -0,0 +1,1009 @@
+/*
+ * form-creator-api. RESTful API to manage and answer forms.
+ * Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+ *
+ * This file is part of form-creator-api.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import { eachSeries, map, waterfall } from "async";
+import { Pool, PoolConfig, QueryResult } from "pg";
+import { Form, FormOptions } from "../core/form";
+import { FormUpdate, FormUpdateOptions } from "../core/formUpdate";
+import { Input, InputOptions, Sugestion, Validation } from "../core/input";
+import { InputUpdate, InputUpdateOptions } from "../core/inputUpdate";
+import { EnumHandler, InputType, UpdateType, ValidationType } from "./enumHandler";
+import { ErrorHandler} from "./errorHandler";
+import { OptHandler } from "./optHandler";
+import { QueryBuilder, QueryOptions } from "./queryBuilder";
+import { Sorter } from "./sorter";
+
+/** Paramenters used to create a temporary Validation */
+interface ValidationTmp {
+    /** Validation identifier */
+    id: number;
+    /** Input id */
+    inputId: number;
+    /** Validation of a input */
+    validation: Validation;
+}
+
+/**
+ * Class used to manage all Form operations into the database.
+ * This operations include read, write and update data.
+ */
+export class FormQueryBuilder extends QueryBuilder {
+
+    constructor(pool: Pool) {
+        super(pool);
+    }
+
+    /**
+     * Asynchronously list all forms using a transaction.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.form - list of form or a empty list if there is no form on database.
+     */
+    public list(cb: (err: Error, result?: Form[]) => void) {
+
+        waterfall([
+            (callback: (err: Error, result?: QueryResult) =>  void) => {
+                this.begin((error: Error, results?: QueryResult) => {
+                    callback(error);
+                });
+            },
+
+            (callback: (err: Error, result?: Form[]) => void) => {
+                this.executeListForms((error: Error, results?: Form[]) => {
+                    callback(error, results);
+                });
+            },
+
+            (forms: Form[], callback: (err: Error, result?: Form[]) => void) => {
+                this.commit((error: Error, results?: QueryResult) => {
+                    callback(error, forms);
+                });
+            }
+
+        ], (err, forms?: Form[]) => {
+            if (err) {
+                this.rollback((error: Error, results?: QueryResult) => {
+                    cb(err);
+                });
+            }
+            cb(null, forms);
+        });
+    }
+
+    /**
+     * Asynchronously get all forms from database without transactions.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.form - list of form or a empty list if there is no form on database.
+     */
+    private executeListForms(cb: (err: Error, result?: Form[]) => void) {
+        const queryString: string = "SELECT id, title, description FROM form;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: []
+        };
+
+        const forms: Form[] = [];
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            if (err) {
+                cb(err);
+                return;
+            }
+
+            for (const row of result.rows) {
+                const formOpt: FormOptions = {
+                    id: row["id"]
+                    , title: row["title"]
+                    , description: row["description"]
+                    , inputs: []
+                };
+
+                const formTmp: Form = new Form(formOpt);
+
+                forms.push(formTmp);
+            }
+
+            cb(null, forms);
+        });
+
+    }
+
+    /**
+     * Asynchronously read a form from database.
+     * @param id - Form identifier to be founded.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.form - Form or null if form not exists.
+     */
+    public read(id: number, cb: (err: Error, form?: Form) => void) {
+
+        waterfall([
+            (callback: (err: Error, result?: QueryResult) =>  void) => {
+                this.begin((error: Error, results?: QueryResult) => {
+                    callback(error);
+                });
+            },
+
+            (callback: (err: Error, result?: Form) => void) => {
+                this.readController(id, (error: Error, resultForm?: Form) => {
+                    callback(error, resultForm);
+                });
+            },
+
+            (form: Form, callback: (err: Error, result?: Form) => void) => {
+                this.commit((error: Error, results?: QueryResult) => {
+                    callback(error, form);
+                });
+            }
+
+        ], (err, form?: Form) => {
+            if (err) {
+                this.rollback((error: Error, results?: QueryResult) => {
+                    cb(err);
+                });
+                return;
+            }
+            cb(null, form);
+        });
+    }
+
+    /**
+     * Asynchronously read a form from database without transactions.
+     * @param id - Form identifier to be founded.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.form - Form or null if form not exists.
+     */
+    private readController(id: number, cb: (err: Error, form?: Form) => void) {
+        waterfall([
+            (callback: (err: Error, result?: Form) => void) => {
+                this.executeReadForm(id, (error: Error, result: QueryResult) => {
+
+                    if (result.rowCount !== 1) {
+                        callback(ErrorHandler.badIdAmount(result.rowCount));
+                        return;
+                    }
+
+                    const formTmp: Form = new Form ({
+                        id: result.rows[0]["id"]
+                        , title: result.rows[0]["title"]
+                        , description: result.rows[0]["description"]
+                        , inputs: []
+                    });
+
+                    callback(null, formTmp);
+                });
+            },
+            (form: Form, callback: (err: Error, form?: Form, resultValidations?: ValidationTmp[]) => void) => {
+                this.executeReadValidation(id, (error: Error, result?: QueryResult) => {
+
+                    if (error) {
+                        callback(error);
+                        return;
+                    }
+
+                    const arrayValidationTmp: ValidationTmp[] = [];
+                    let validationTmp: any;
+                    for (const i of result.rows) {
+                        validationTmp = {
+                            id: i["id"]
+                            , inputId: i["id_input"]
+                            , validation: {
+                                type: EnumHandler.parseValidationType(i["validation_type"])
+                                , arguments: []
+                            }
+                        };
+                        arrayValidationTmp.push(validationTmp);
+                    }
+
+                    callback(null, form, Sorter.sortById(arrayValidationTmp));
+                });
+            },
+            (form: Form, validations: ValidationTmp[], callback: (err: Error, form?: Form, resultValidations?: ValidationTmp[]) => void) => {
+
+                this.executeReadArgument(id, (error: Error, result?: QueryResult) => {
+
+                    if (error) {
+                        callback(error);
+                        return;
+                    }
+
+                    const sortedResults: any = Sorter.sortById(result.rows);
+                    let k: number = 0;
+                    let i: number = 0;
+                    while ((i < validations.length) && (k < sortedResults.length)) {
+                        if (validations[i].id === sortedResults[k].id_validation) {
+                            validations[i].validation.arguments.push(sortedResults[k].argument);
+                            k++;
+                        }
+                        else {
+                            i++;
+                        }
+                    }
+                    callback(null, form, validations);
+                });
+            },
+            (form: Form, validations: ValidationTmp[], callback: (err: Error, form?: Form, resultInputs?: Input[]) => void) => {
+                this.executeReadInput(id, (error: Error, result: QueryResult) => {
+
+                    if (error) {
+                        callback(error);
+                        return;
+                    }
+
+                    const validationArray: any = Sorter.sortByInputId(validations);
+                    const inputArrayTmp: Input[] = [];
+                    let inputTmp: InputOptions;
+
+                    for (const i of result.rows) {
+                        inputTmp = {
+                            id: i["id"]
+                            , placement: i["placement"]
+                            , description: i["description"]
+                            , question: i["question"]
+                            , type: EnumHandler.parseInputType(i["input_type"])
+                            , enabled: i["enabled"]
+                            , validation: []
+                            , sugestions: []
+                        };
+                        inputArrayTmp.push(new Input(inputTmp));
+                    }
+
+                    let j: number = 0;
+                    let k: number = 0;
+                    while ((j < inputArrayTmp.length) && (k < validationArray.length)) {
+                        if (inputArrayTmp[j].id === validationArray[k].inputId){
+                            inputArrayTmp[j].validation.push(validationArray[k].validation);
+                            k++;
+                        } else {
+                            j++;
+                        }
+                    }
+
+                    callback(null, form, Sorter.sortByPlacement(inputArrayTmp));
+                });
+            },
+            (form: Form, inputs: Input[], callback: (err: Error, form?: Form) => void) => {
+                this.executeReadSugestion(id, (error: Error, result: QueryResult) => {
+
+                    if (error) {
+                        callback(error);
+                        return;
+                    }
+
+                    let i: number = 0;
+                    let k: number = 0;
+                    while ((i < inputs.length) && (k < result.rows.length)) {
+                        if (inputs[i].id === result.rows[k]["id_input"]) {
+                            inputs[i].sugestions.push({value: result.rows[k]["value"], placement: result.rows[k]["placement"]});
+                            k++;
+                        } else {
+                            i++;
+                        }
+                    }
+
+                    for (const j of inputs) {
+                        form.inputs.push(j);
+                    }
+
+                    callback(null, form);
+                });
+            }
+        ], (err, result?: Form) => {
+            if (err) {
+                cb(err);
+                return;
+            }
+            cb(null, result);
+        });
+    }
+
+    /**
+     * Asynchronously read a form without transactions.
+     * @param id - Form identifier to be founded.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.form - Form or null if form not exists.
+     */
+    private executeReadForm(id: number, cb: (err: Error, form?: QueryResult) => void) {
+        const queryString: string = "SELECT id, title, description FROM form WHERE id=$1;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [id]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err, result);
+        });
+    }
+
+    /**
+     * Asynchronously read inputs from database without transactions.
+     * @param id - Form identifier which inputs are linked to.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.form - Form or null if form not exists.
+     */
+    private executeReadInput(id: number, cb: (err: Error, result?: QueryResult) => void) {
+        const queryString: string = "SELECT input.id, id_form, placement, input_type, question, \
+                                    enabled, input.description FROM form f \
+                                    INNER JOIN input ON f.id=id_form \
+                                    WHERE f.id=$1 AND enabled=true ORDER BY input.id;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [id]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err, result);
+        });
+    }
+
+    /**
+     * Asynchronously read validations from database without transactions.
+     * @param id - Form identifier which validations from inputs are linked to.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.form - Form or null if form not exists.
+     */
+    private executeReadValidation(id: number, cb: (err: Error, result?: QueryResult) => void) {
+        const queryString: string = "SELECT input_validation.id, id_input, validation_type FROM form f \
+                                    INNER JOIN input ON f.id=id_form \
+                                    INNER JOIN input_validation ON input.id=id_input \
+                                    WHERE f.id=$1 AND enabled=true;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [id]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err, result);
+        });
+    }
+
+    /**
+     * Asynchronously read arguments from database without transactions.
+     * @param id - Form identifier which arguments from validatation are linked to.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.form - Form or null if form not exists.
+     */
+    private executeReadArgument(id: number, cb: (err: Error, result?: QueryResult) => void) {
+        const queryString: string = "SELECT input_validation_argument.id, id_input_validation AS id_validation, \
+                                     input_validation_argument.placement, argument FROM form f\
+                                     INNER JOIN input i ON f.id=id_form \
+                                     INNER JOIN input_validation iv ON i.id=id_input \
+                                     INNER JOIN input_validation_argument ON iv.id=id_input_validation \
+                                     WHERE f.id=$1 AND enabled=true;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [id]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err, result);
+        });
+    }
+
+    /**
+     * Asynchronously read sugestions from database without transactions.
+     * @param id - Form identifier wich arguments from inputs are linked to.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.form - Form or null if form not exists.
+     */
+    private executeReadSugestion(id: number, cb: (err: Error, result?: QueryResult) => void) {
+        const queryString: string = "SELECT input_sugestion.id, id_input, value, input_sugestion.placement \
+                                     FROM form f \
+                                     INNER JOIN input ON f.id=id_form \
+                                     INNER JOIN input_sugestion ON input.id=id_input \
+                                     WHERE f.id=$1 AND enabled=true ORDER BY input.id;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [id]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err, result);
+        });
+    }
+
+    /**
+     * Asynchronously write a form on database.
+     * @param form - Form to be inserted.
+     * @param cb - Callback function which contains the inserted data.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.formResult - Form or null if form any error occurs.
+     */
+    public write(form: Form, cb: (err: Error, form?: Form) => void) {
+        waterfall([
+            (callback: (err: Error, result?: QueryResult) => void) => {
+                this.begin((error: Error, results?: QueryResult) => {
+                    callback(error);
+                });
+            },
+            (callback: (err: Error, result?: number) => void) => {
+                this.writeController(form, (error: Error, resultId?: number) => {
+                    callback(error, resultId);
+                });
+            },
+            (formId: number, callback: (err: Error, result?: number) => void) => {
+                this.commit((error: Error, results?: QueryResult) => {
+                    callback(error, formId);
+                });
+            },
+            (formId: number, callback: (err: Error, result?: Form) => void) => {
+                this.read(formId, (error: Error, resultForm?: Form) => {
+                    callback(error, resultForm);
+                });
+            }
+        ], (err, formResult?: Form) => {
+            if (err) {
+                this.rollback((error: Error, results?: QueryResult) => {
+                    cb(err);
+                });
+                return;
+            }
+            cb(null, formResult);
+        });
+    }
+
+    /**
+     * Asynchronously write a form on database without transactions.
+     * @param form - Form to be inserted.
+     * @param cb - Callback function which contains the inserted data.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.formId - Form identifier or null if form any error occurs.
+     */
+    private writeController(form: Form, cb: (Err: Error, formId?: number) => void) {
+        waterfall([
+            (callback: (err: Error, result?: number) => void) => {
+                this.executeWriteForm(form, (error: Error, resultId?: number) => {
+                    callback(error, resultId);
+                });
+            },
+            (formId: number, callback: (err: Error, result?: number) => void) => {
+                this.writeInputController(formId, form.inputs, (error: Error) => {
+                    callback(error, formId);
+                });
+            }
+        ], (err, id: number) => {
+            if (err) {
+                cb(err);
+            }
+            cb(null, id);
+        });
+
+    }
+
+    /**
+     * Asynchronously write a input on database without transactions.
+     * @param formId - Form identifier which inputs are linked to.
+     * @param inputs - A list of inputs to be inserted.
+     * @param cb - Callback function which contains informations about method's execution.
+     * @param cb.err - Error information when the method fails.
+     */
+    private writeInputController(formId: number, inputs: Input[], cb: (err: Error) => void) {
+        eachSeries(inputs, (input, outerCallback) => {
+            waterfall([
+                (callback: (err: Error, result?: number) => void) => {
+                    this.executeWriteInput(formId, input, (error: Error, resultInputId?: number) => {
+                        if (error) {
+                            callback(error);
+                            return;
+                        }
+                        callback(null, resultInputId);
+                    });
+                },
+                (inputId: number, callback: (err: Error, resultInputId?: number) => void) => {
+                    this.writeValidationController(inputId, input.validation, (error: Error) => {
+                        callback(error, inputId);
+                    });
+                },
+                (inputId: number, callback: (err: Error) => void) => {
+                    this.writeSugestionController(inputId, input.sugestions, (error: Error) => {
+                        callback(error);
+                    });
+                }
+            ], (err) => {
+                if (err) {
+                    outerCallback(err);
+                    return;
+                }
+                outerCallback(null);
+            });
+        }, (e) => {
+            cb(e);
+        });
+    }
+
+    /**
+     * Asynchronously write a validation on database without transactions.
+     * @param inputId - Input identifier which validations are linked to.
+     * @param validations - A list of validations to be inserted.
+     * @param cb - Callback function which contains informations about method's execution.
+     * @param cb.err - Error information when the method fails.
+     */
+    private writeValidationController(inputId: number, validations: Validation[], cb: (err: Error) => void) {
+        let i: number;
+
+        eachSeries(validations, (validation, callback) => {
+            this.executeWriteValidation(inputId, validation, (err: Error, validationId?: number) => {
+                i = 0;
+                eachSeries(validation.arguments, (argument, innerCallback) => {
+                    this.executeWriteArgument(validationId, argument, i++, innerCallback);
+                }, (error) => {
+                    callback(error);
+                });
+            });
+        }, (err) => {
+            cb(err);
+        });
+    }
+
+    /**
+     * Asynchronously write a sugestion on database without transactions.
+     * @param inputId - Input identifier which sugestions are linked to.
+     * @param sugestions - A list of sugestions to be inserted.
+     * @param cb - Callback function which contains informations about method's execution.
+     * @param cb.err - Error information when the method fails.
+     */
+    private writeSugestionController(inputId: number, sugestions: Sugestion[], cb: (err: Error) => void) {
+        eachSeries(sugestions, (sugestion, callback) => {
+            this.executeWriteSugestion(inputId, sugestion, callback);
+        }, (err) => {
+            cb(err);
+        });
+    }
+
+    /**
+     * Asynchronously insert a form on database without transactions.
+     * @param form - Form to be inserted.
+     * @param cb - Callback function which contains informations about method's execution.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.result - Form identifier or null if any error occurs.
+     */
+    private executeWriteForm(form: Form, cb: (err: Error, result?: number) => void) {
+        const queryString: string = "INSERT INTO form (title, description) \
+                                     VALUES ($1, $2) \
+                                     RETURNING id;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [
+                form.title
+                , form.description
+            ]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            if (err) {
+                cb(err);
+                return;
+            }
+            cb(null, result.rows[0]["id"]);
+        });
+    }
+
+    /**
+     * Asynchronously insert a input on database without transactions.
+     * @param formId - Form identifier which input are linked to.
+     * @param input - A input to be inserted.
+     * @param cb - Callback function which contains informations about method's execution.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.resultId - Input identifier or null if any error occurs.
+     */
+    private executeWriteInput(formId: number, input: Input, cb: (err: Error, resultId?: number) => void) {
+        const queryString: string = "INSERT INTO input (id_form, placement, input_type, enabled, question, description) \
+                                     VALUES ($1, $2, $3, $4, $5, $6) \
+                                     RETURNING id;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [
+                formId
+                , input.placement
+                , EnumHandler.stringifyInputType(input.type)
+                , true
+                , input.question
+                , input.description
+            ]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err, result.rows[0]["id"]);
+        });
+    }
+
+    /**
+     * Asynchronously insert a validation on database without transactions.
+     * @param inputId - Input identifier which validations are linked to.
+     * @param cb - Callback function which contains informations about method's execution.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.result - Validation identifier or null if any error occurs.
+     */
+    private executeWriteValidation(inputId: number, validation: Validation, cb: (err: Error, result?: number) => void) {
+        const queryString: string = "INSERT INTO input_validation (id_input, validation_type) \
+                                     VALUES ($1, $2) \
+                                     RETURNING id;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [
+                inputId
+                , EnumHandler.stringifyValidationType(validation.type)
+            ]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err, result.rows[0]["id"]);
+        });
+    }
+
+    /**
+     * Asynchronously insert a argument on database without transactions.
+     * @param validationId - Validation identifier which argument are linked to.
+     * @param argument - The argument string to be inserted.
+     * @param cb - Callback function which contains informations about method's execution.
+     * @param cb.err - Error information when the method fails.
+     */
+    private executeWriteArgument(validationId: number, argument: string, placement: number, cb: (err: Error) => void) {
+        const queryString: string = "INSERT INTO input_validation_argument (id_input_validation, argument, placement) \
+                                     VALUES ($1, $2, $3) \
+                                     RETURNING id;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [
+                validationId
+                , argument
+                , placement
+            ]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err);
+        });
+    }
+
+    /**
+     * Asynchronously insert a sugestion on database without transactions.
+     * @param inputId - Input identifier which sugestion are linked to.
+     * @param cb - Callback function which contains informations about method's execution.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.result - Form identifier or null if any error occurs.
+     */
+    private executeWriteSugestion(inputId: number, sugestion: Sugestion, cb: (err: Error) => void) {
+        const queryString: string = "INSERT INTO input_sugestion (id_input, value, placement) \
+                                     VALUES ($1, $2, $3);";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [
+                inputId
+                , sugestion.value
+                , sugestion.placement
+            ]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err);
+        });
+    }
+
+    /**
+     * Asynchronously update a form on database.
+     * @param form - Form to be updated.
+     * @param cb - Callback function which contains information about method's execution.
+     * @param cb.err - Error information when the method fails.
+     */
+    public update(formUpdate: FormUpdate, cb: (err: Error) => void) {
+        waterfall([
+            (callback: (err: Error, result?: QueryResult) =>  void) => {
+                this.begin((error: Error, results?: QueryResult) => {
+                    callback(error);
+                });
+            },
+            (callback: (err: Error, result?: Form) => void) => {
+                this.updateController(formUpdate, (error: Error, resultForm?: Form) => {
+                    callback(error, resultForm);
+                });
+            },
+            (form: Form, callback: (err: Error, result?: Form) => void) => {
+                this.commit((error: Error, results?: QueryResult) => {
+                    callback(error, form);
+                });
+            }
+        ], (err) => {
+            if (err) {
+                this.rollback((error: Error, results?: QueryResult) => {
+                    cb(err);
+                });
+                return;
+            }
+            cb(null);
+        });
+    }
+
+    /**
+     * Asynchronously update a form on database without transactions.
+     * @param formUpdate - FormUpdate object that contains the data to update.
+     * @param cb - Callback function which contains informations about method's execution.
+     * @param cb.err - Error information when the method fails.
+     */
+    private updateController(formUpdate: FormUpdate, cb: (err: Error) => void) {
+        waterfall([
+            // Update form fields on database
+            (callback: (err: Error) => void) => {
+                if (formUpdate.changed) {
+                    this.updateFormController(formUpdate.form, (error: Error) => {
+                        callback(error);
+                    });
+                } else {
+                    callback(null);
+                }
+            },
+            // Update inputs on database
+            (callback: (err: Error, formUpdateResult?: FormUpdate) => void) => {
+                this.updateInputsController(formUpdate.form.id, formUpdate.inputUpdates, (error: Error, inputUpdateResult: InputUpdate[]) => {
+                    if (error) {
+                        callback(error);
+                        return;
+                    }
+
+                    const formUpdateTmp: FormUpdate = {
+                        id: formUpdate.id
+                        , form: formUpdate.form
+                        , updateDate: formUpdate.updateDate
+                        , changed: formUpdate.changed
+                        , inputUpdates: inputUpdateResult
+                    };
+
+                    callback(null, formUpdateTmp);
+                });
+            },
+            // Write formUpdate on database
+            (formUpdateTmp: FormUpdate, callback: (err: Error, formUpdateTmp?: FormUpdate, resultId?: number) => void) => {
+                this.executeWriteFormUpdate(formUpdateTmp, (error: Error, formUpdateResultId?: number) => {
+                    if (error) {
+                        callback(error);
+                        return;
+                    }
+                    callback(null, formUpdateTmp, formUpdateResultId);
+                });
+            },
+            // Write inputUpdate on database
+            (formUpdateTmp: FormUpdate, formUpdateId: number, callback: (err: Error) => void) => {
+                eachSeries(formUpdateTmp.inputUpdates, (inputUpdate, innerCallback) => {
+                    this.executeWriteInputUpdate(formUpdateId, inputUpdate, innerCallback);
+                }, (err) => {
+                    callback(err);
+                });
+            }
+        ], (err) => {
+            cb(err);
+        });
+    }
+
+    /**
+     * Asynchronously update a form on database.
+     * @param form - Form to be updated.
+     * @param cb - Callback function which contains information about method's execution.
+     * @param cb.err - Error information when the method fails.
+     */
+    private updateFormController(form: Form, cb: (err: Error) => void) {
+        waterfall([
+            (callback: (err: Error) => void) => {
+                this.executeUpdateForm(form.title, form.id, "title", callback);
+            },
+            (callback: (err: Error) => void) => {
+                this.executeUpdateForm(form.description, form.id, "description", callback);
+            }
+        ], (error) => {
+            cb(error);
+        });
+    }
+
+    /**
+     * Asynchronously update a list of inputs on database.
+     * @param formId - Form identifier which update are linked to.
+     * @param inputUpdates - InputUpdate array which contains the update information.
+     * @param cb - Callback function which contains information about method's execution.
+     * @param cb.err - Error information when the method fails.
+     * @param inputUpdateResult - InputUpdate or null if method fails.
+     */
+    private updateInputsController(formId: number, inputUpdates: InputUpdate[], cb: (err: Error, inputUpdateResult?: InputUpdate[]) => void) {
+
+        const inputUpdatesTmp: InputUpdate[] = [];
+
+        eachSeries(inputUpdates, (inputUpdate, callback) => {
+            switch (inputUpdate.inputOperation) {
+                case UpdateType.ADD: {
+                    this.executeWriteInput(formId, inputUpdate.input, (err: Error, id: number) => {
+
+                        if (err) {
+                            callback(err);
+                            return;
+                        }
+
+                        const inputOpt: InputOptions = inputUpdate.input;
+                        inputOpt.id = id;
+
+                        const inputUpdateOpt: InputUpdateOptions = {
+                            input: inputOpt
+                            , inputOperation: UpdateType.ADD
+                            , value: null
+                        };
+                        inputUpdatesTmp.push(new InputUpdate(inputUpdateOpt));
+                        callback(null);
+                    });
+                    break;
+                }
+                case UpdateType.REMOVE: {
+                    // Set enabled option in database as false
+                    this.executeUpdateInput(0, inputUpdate.input.id, "enabled", (err: Error) => {
+
+                        if (err) {
+                            callback(err);
+                            return;
+                        }
+
+                        inputUpdatesTmp.push(inputUpdate);
+                        callback(null);
+                    });
+                    break;
+                }
+                case UpdateType.SWAP: {
+                    // Update placement option in database of a input
+                    this.executeUpdateInput(inputUpdate.input.placement, inputUpdate.input.id, "placement", (err: Error) => {
+
+                        if (err) {
+                            callback(err);
+                            return;
+                        }
+
+                        inputUpdatesTmp.push(inputUpdate);
+                        callback(null);
+                    });
+                    break;
+                }
+                case UpdateType.REENABLED: {
+                    // Set enabled option in database as true
+                    this.executeUpdateInput(1, inputUpdate.input.id, "enabled", (err: Error) => {
+
+                        if (err) {
+                            callback(err);
+                            return;
+                        }
+
+                        inputUpdatesTmp.push(inputUpdate);
+                        callback(null);
+                    });
+                    break;
+                }
+                default: {
+                    callback(new Error ("Operation " + inputUpdate.inputOperation  + " not recognized"));
+                    break;
+                }
+            }
+        }, (error) => {
+            if (error) {
+                cb(error);
+                return;
+            }
+            cb(null, inputUpdatesTmp);
+        });
+    }
+
+    /**
+     * Asynchronously update form's fields on database.
+     * @param value - A string to be inserted in the database.
+     * @param id - The form id that should be updated.
+     * @param field - The field on database that should be updated.
+     * @param cb - Callback function.
+     * @param cb.err - Error information when method fails.
+     */
+    private executeUpdateForm(value: string, id: number, field: string, cb: (err: Error) => void) {
+        const queryString: string = "UPDATE form SET " + field + " = $1 WHERE id = $2";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [
+                value
+                , id
+            ]
+        };
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err);
+        });
+    }
+
+    /**
+     * Asynchronously update a input field on database.
+     * @param value - A number to be inserted in the database.
+     * @param id - The input id that should be updated.
+     * @param field - The field on database that should be updated.
+     * @param cb - Callback function.
+     * @param cb.err - Error information when the method fails.
+     */
+    private executeUpdateInput(value: number, id: number, field: string, cb: (err: Error) => void) {
+        const queryString: string = "UPDATE input SET " + field + " = $1 WHERE id = $2";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [
+                value
+                , id
+            ]
+        };
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err);
+         });
+    }
+
+    /**
+     * Asynchronously insert a formUpdate on database.
+     * @param formUpdate - Form Update to be inserted.
+     * @param cb - Callback function.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.formUpdateId - The id of the inserted FormUpdate.
+     */
+    private executeWriteFormUpdate(formUpdate: FormUpdate, cb: (err: Error, formUpdateId?: number) => void) {
+
+        const queryString: string = "INSERT INTO form_update (id_form, update_date) \
+                                     VALUES ( $1, $2 ) \
+                                     RETURNING id;";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [
+                formUpdate.form.id
+                , formUpdate.updateDate
+            ]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            if (err) {
+                cb(err);
+                return;
+            }
+            cb(null, result.rows[0].id);
+        });
+    }
+
+    /**
+     * Asynchronously insert a inputUpdate on database.
+     * @param inputUpdate - Input Update to be inserted.
+     * @param cb - Callback function.
+     * @param cb.err - Error information when the method fails.
+     */
+    private executeWriteInputUpdate(idFormUpdate: number, inputUpdate: InputUpdate, cb: (err: Error) => void) {
+
+        const queryString: string = "INSERT INTO input_update (id_form_update, id_input, input_operation_id, value) \
+                                     VALUES ( $1, $2, $3, $4 );";
+        const query: QueryOptions = {
+            query: queryString
+            , parameters: [
+                idFormUpdate
+                , inputUpdate.input.id
+                , inputUpdate.inputOperation
+                , inputUpdate.value
+            ]
+        };
+
+        this.executeQuery(query, (err: Error, result?: QueryResult) => {
+            cb(err);
+        });
+    }
+}
diff --git a/src/utils/optHandler.spec.ts b/src/utils/optHandler.spec.ts
index 19a542f5fa1ea2a2dd26a59d5c4b55ebc0fd6f9f..5170308e67bcbe00450de8d431b5dece573fced4 100644
--- a/src/utils/optHandler.spec.ts
+++ b/src/utils/optHandler.spec.ts
@@ -1347,4 +1347,56 @@ describe("Options Handler", () => {
             expect(updateTmp).to.be.a("undefined");
         }
     });
+
+    it("should get error Input with malformed sugestion missing key 'placement'", () => {
+
+        const inputObj: any = {
+            placement: 1
+            , description: "Description Question 2 Form 1"
+            , question:  "Question 2 Form 1"
+            , type: InputType.TEXT
+            , validation: []
+            , sugestions: [
+                { value: "Malformed Sugestion" }
+                , { value: "Sugestion", placement: 0 }
+            ]
+            , id: 1
+        };
+
+        let inputTmp: Input;
+
+        try {
+            inputTmp = new Input(OptHandler.input(inputObj));
+        } catch (e) {
+            expect(e).to.be.not.a("null");
+            expect(e.message).to.be.equal(ErrorHandler.notFound("Sugestion placement").message);
+            expect(inputTmp).to.be.a("undefined");
+        }
+    });
+
+    it("should get error Input with malformed sugestion missing key 'value'", () => {
+
+        const inputObj: any = {
+            placement: 1
+            , description: "Description Question 2 Form 1"
+            , question:  "Question 2 Form 1"
+            , type: InputType.TEXT
+            , validation: []
+            , sugestions: [
+                { placement: 0}
+                , { value: "Sugestion", placement: 1 }
+            ]
+            , id: 1
+        };
+
+        let inputTmp: Input;
+
+        try {
+            inputTmp = new Input(OptHandler.input(inputObj));
+        } catch (e) {
+            expect(e).to.be.not.a("null");
+            expect(e.message).to.be.equal(ErrorHandler.notFound("Sugestion value").message);
+            expect(inputTmp).to.be.a("undefined");
+        }
+    });
 });
diff --git a/src/utils/optHandler.ts b/src/utils/optHandler.ts
index 36e8d46e3086bc427dc27ecb2861d54bc77e8ec2..e2bc778c2930359b0de2b7fc2b55609a92f11e4c 100644
--- a/src/utils/optHandler.ts
+++ b/src/utils/optHandler.ts
@@ -19,23 +19,23 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-    import { Form, FormOptions } from "../core/form";
-    import { FormAnswerOptions } from "../core/formAnswer";
-    import { FormUpdate, FormUpdateOptions } from "../core/formUpdate";
-    import { InputOptions, Validation } from "../core/input";
-    import { InputAnswer, InputAnswerDict, InputAnswerOptions, InputAnswerOptionsDict } from "../core/inputAnswer";
-    import { InputUpdate, InputUpdateOptions } from "../core/inputUpdate";
-    import { InputType, UpdateType} from "./enumHandler";
-    import { ErrorHandler} from "./errorHandler";
+import { Form, FormOptions } from "../core/form";
+import { FormAnswerOptions } from "../core/formAnswer";
+import { FormUpdate, FormUpdateOptions } from "../core/formUpdate";
+import { InputOptions, Sugestion, Validation } from "../core/input";
+import { InputAnswer, InputAnswerDict, InputAnswerOptions, InputAnswerOptionsDict } from "../core/inputAnswer";
+import { InputUpdate, InputUpdateOptions } from "../core/inputUpdate";
+import { InputType, UpdateType} from "./enumHandler";
+import { ErrorHandler} from "./errorHandler";
 /**
  * OptHandler to handle an object and transform into a Classoptions to be used in Class's constructor
  */
-    export class OptHandler {
-     /**
-      * Return an FormOptions instance with a parsed object, The main objective is parse any error previously
-      * @param obj - object that should be parsed.
-      * @returns - An FormOptions instance.
-      */
+export class OptHandler {
+    /**
+     * Return an FormOptions instance with a parsed object, The main objective is parse any error previously
+     * @param obj - object that should be parsed.
+     * @returns - An FormOptions instance.
+     */
     public static form(obj: any): FormOptions{
 
         if (obj.title === undefined ){
@@ -89,9 +89,16 @@
             type: obj.type,
             validation: obj.validation.map((v: any) => {
                 return {type: v.type, arguments: v.arguments};
-            })
+            }),
+            sugestions: []
         };
 
+        if (obj.sugestions instanceof Array) {
+            option.sugestions = obj.sugestions.map((v: any) => {
+                return OptHandler.sugestion(v);
+            });
+        }
+
         return option;
     }
 
@@ -117,7 +124,6 @@
             inputsAnswerOptionsTmp[parseInt(key, 10)] =  obj.inputsAnswerOptions[parseInt(key, 10)].map( (i: InputAnswerOptions) => {
                 return OptHandler.inputAnswer(i);
             });
-
         }
 
         const option: FormAnswerOptions = {
@@ -157,7 +163,7 @@
     }
 
     /**
-     * Return an FormUpdateOptions instance with a parsed and validated object, The main objective is parse any error previously
+     * Return an FormUpdateOptions instance with a parsed and validated object. The main objective is parse any error previously
      * @param obj - object that should be parsed.
      * @returns - An FormUpdateOptions instance.
      */
@@ -180,7 +186,7 @@
     }
 
     /**
-     * Return an FormUpdateOptions instance with a parsed and validated object, The main objective is to detect parsing errors previously
+     * Return an FormUpdateOptions instance with a parsed and validated object. The main objective is to detect parsing errors previously
      * @param obj - object that should be parsed.
      * @returns - An FormUpdateOptions instance.
      */
@@ -205,4 +211,25 @@
         return option;
     }
 
+    /**
+     * Return a parsed and validated sugestion.
+     * @param obj - object that should be parsed.
+     * @returns - Sugestion instance.
+     */
+    public static sugestion(obj: any): Sugestion {
+
+        if (typeof(obj.value) !== "string") {
+            throw ErrorHandler.notFound("Sugestion value");
+        }
+        if (typeof(obj.placement) !== "number") {
+            throw ErrorHandler.notFound("Sugestion placement");
+        }
+
+        const option: Sugestion = {
+            value: obj.value
+            , placement: obj.placement
+        };
+
+        return option;
+    }
 }
diff --git a/src/utils/queryBuilder.ts b/src/utils/queryBuilder.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b8ef174b266c5d870265388a935f1643c4ead0f4
--- /dev/null
+++ b/src/utils/queryBuilder.ts
@@ -0,0 +1,93 @@
+/*
+ * form-creator-api. RESTful API to manage and answer forms.
+ * Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+ *
+ * This file is part of form-creator-api.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import { Pool, PoolConfig, QueryResult } from "pg";
+
+/** Parameters used to create a parametrized query, to avoid SQL injection */
+export interface QueryOptions {
+    /** Query string to execute */
+    query: string;
+    /** Array of input. containing question */
+    parameters: any[];
+}
+
+/**
+ * Class used to build and execute queries in the database.
+ * Querybuilder classes should be used to abstract the access of objects in the database.
+ */
+export abstract class QueryBuilder {
+
+    /** Information used to connect with a PostgreSQL database. */
+    private pool: Pool;
+
+    /**
+     * Creates a new adapter with the database connection configuration.
+     * @param config - The information required to create a connection with the database.
+     */
+    constructor(pool: Pool) {
+        this.pool = pool;
+    }
+
+    /**
+     * Asynchronously executes a query and get its result.
+     * @param query - Query (SQL format) to be executed.
+     * @param cb - Callback function which contains the data read.
+     * @param cb.err - Error information when the method fails.
+     * @param cb.result - Query result.
+     */
+    public executeQuery(query: QueryOptions, cb: (err: Error, result?: QueryResult) => void): void {
+
+        this.pool.connect((err, client, done) => {
+
+            if (err) {
+                cb(err);
+                return;
+            }
+
+            client.query(query.query, query.parameters, (error, result) => {
+                // call 'done()' to release client back to pool
+                done();
+                cb(error, (result) ? result : null);
+            });
+        });
+    }
+
+    /**
+     * Asynchronously ends a transaction
+     */
+    public commit(cb: (err: Error, result?: QueryResult) => void) {
+        this.executeQuery({query: "COMMIT;", parameters: []}, cb);
+    }
+
+    /**
+     * Asynchronously rollback a transaction
+     */
+    public rollback(cb: (err: Error, result?: QueryResult) => void) {
+        this.executeQuery({query: "ROLLBACK;", parameters: []}, cb);
+    }
+
+    /**
+     * Asynchronously starts a transaction
+     */
+    public begin(cb: (err: Error, result?: QueryResult) => void) {
+        this.executeQuery({query: "BEGIN;", parameters: []}, cb);
+    }
+}
diff --git a/src/utils/sorter.ts b/src/utils/sorter.ts
index 41414791a6318fd9066802c41d7d43ef6559ed10..64156fc714cfe63ece9a54e2f1c57f9febe5fc37 100644
--- a/src/utils/sorter.ts
+++ b/src/utils/sorter.ts
@@ -22,7 +22,7 @@
 export class Sorter {
 
     /**
-     * A public method to return a array sorted by placement field
+     * A method to return a array sorted by placement field
      * @param array - Array with objects that have placement field
      * @returns - A sorted array by placement
      */
@@ -44,7 +44,7 @@ export class Sorter {
     }
 
     /**
-     * A public method to return a array sorted by id field
+     * A method to return a array sorted by id field
      * @param array - Array with objects that have id field
      * @returns - A sorted array by id
      */
@@ -64,4 +64,26 @@ export class Sorter {
 
         return sortedByIdArray;
     }
+
+    /**
+     * A method to return a array sorted by inputId field
+     * @param array - Array with objects that have id field
+     * @returns - A sorted array by id
+     */
+    public static sortByInputId(array: any[]): any[] {
+
+        const sortedByInputIdArray: any[] = array.sort((obj1, obj2) => {
+            if (obj1["inputId"] > obj2["inputId"]) {
+                return 1;
+            }
+
+            if (obj1["inputId"] < obj2["inputId"]) {
+                return -1;
+            }
+
+            return 0;
+        });
+
+        return sortedByInputIdArray;
+    }
 }
diff --git a/src/utils/validationError.ts b/src/utils/validationError.ts
index f440f973c472edac87d2f20e45aca7a52ea8d53e..ea4e967cff9b142a9ba6487fec30b1a7104b6459 100644
--- a/src/utils/validationError.ts
+++ b/src/utils/validationError.ts
@@ -31,11 +31,11 @@
   * ValidationError: Extends Error class
   * Has a dict that allow us to know which answer is invalide
   */
- export class ValidationError extends Error{
+ export class ValidationError extends Error {
      /** A dict that allows user to know which Input Answer is invalid. */
      public readonly validationDict: ValidationDict;
 
-     constructor(validationDict: ValidationDict, ...params: any[]){
+     constructor(validationDict: ValidationDict, ...params: any[]) {
          super(...params);
          this.validationDict = validationDict;
      }
diff --git a/src/utils/validationHandler.spec.ts b/src/utils/validationHandler.spec.ts
index d526f647145ab5483979a418195556e42a3bbfda..996ade015ec5f63cd983f9d1b52d98e4ef92477c 100644
--- a/src/utils/validationHandler.spec.ts
+++ b/src/utils/validationHandler.spec.ts
@@ -48,11 +48,13 @@ describe("Validation Handler", () => {
             , 5: [inputAnswersOpt2]
         };
 
-        const data: Date = new Date(2019, 6, 4);
-        dbhandler.readForm(2, (error: Error, form: Form) => {
+        const date: Date = new Date(2019, 6, 4);
+        dbhandler.form.read(2, (error: Error, form: Form) => {
+            expect(error).to.be.a("null");
+
             const formAnswerOptions: FormAnswerOptions = {
                 form
-                , timestamp: data
+                , timestamp: date
                 , inputsAnswerOptions: inputAnswerOptionsDict
             };
             const formAnswer = new FormAnswer(OptHandler.formAnswer(formAnswerOptions));
@@ -83,7 +85,7 @@ describe("Validation Handler", () => {
         };
 
         const data: Date = new Date(2019, 6, 4);
-        dbhandler.readForm(2, (error: Error, form: Form) => {
+        dbhandler.form.read(2, (error: Error, form: Form) => {
             const formAnswerOptions: FormAnswerOptions = {
                 form
                 , timestamp: data
@@ -123,7 +125,7 @@ describe("Validation Handler", () => {
             , 3: [inputAnswersOpt3]
         };
         const data: Date = new Date(2019, 6, 4);
-        dbhandler.readForm(1, (error: Error, form: Form) => {
+        dbhandler.form.read(1, (error: Error, form: Form) => {
             const formAnswerOptions: FormAnswerOptions = {
                 form
                 , timestamp: data
@@ -165,7 +167,7 @@ describe("Validation Handler", () => {
             , 3: [inputAnswersOpt3]
         };
         const data: Date = new Date(2019, 6, 4);
-        dbhandler.readForm(1, (error: Error, form: Form) => {
+        dbhandler.form.read(1, (error: Error, form: Form) => {
             const formAnswerOptions: FormAnswerOptions = {
                 form
                 , timestamp: data
@@ -181,7 +183,158 @@ describe("Validation Handler", () => {
             }
             done();
         });
+    });
+
+    it("should test when input is number", (done) => {
 
+        const inputAnswerOpt1: InputAnswerOptions = {
+            idInput: 23
+            , placement: 0
+            , value: "Not a number"
+        };
+
+        const inputAnswerOpt2: InputAnswerOptions = {
+            idInput: 23
+            , placement: 0
+            , value: "23"
+        };
+
+        const inputAnswerOpt3: InputAnswerOptions = {
+            idInput: 23
+            , placement: 0
+            , value: "24"
+        };
+
+        const inputAnswerOpt4: InputAnswerOptions = {
+            idInput: 24
+            , placement: 0
+            , value: "25"
+        };
+
+        const inputAnswerOpt5: InputAnswerOptions = {
+            idInput: 25
+            , placement: 0
+            , value: "Not a Float"
+        };
+
+        const inputAnswerOpt6: InputAnswerOptions = {
+            idInput: 26
+            , placement: 0
+            , value: "1.83"
+        };
+        const inputAnswerOpt7: InputAnswerOptions = {
+            idInput: 27
+            , placement: 0
+            , value: "Not a date"
+        };
+
+        const inputAnswerOpt8: InputAnswerOptions = {
+            idInput: 28
+            , placement: 0
+            , value: "02/02/2002"
+        };
+
+        const inputAnswerOpt9: InputAnswerOptions = {
+            idInput: 29
+            , placement: 0
+            , value: "Invalid argument causes invalid answer"
+        };
+
+        const inputAnswerOptionsDict: InputAnswerOptionsDict = {
+            23: [
+                inputAnswerOpt1
+                , inputAnswerOpt2
+                , inputAnswerOpt3
+            ]
+            , 24: [inputAnswerOpt4]
+            , 25: [inputAnswerOpt5]
+            , 26: [inputAnswerOpt6]
+            , 27: [inputAnswerOpt7]
+            , 28: [inputAnswerOpt8]
+            , 29: [inputAnswerOpt9]
+        };
+
+        dbhandler.form.read(7, (error: Error, form: Form) => {
+            const formAnswerOptions: FormAnswerOptions = {
+                form
+                , timestamp: new Date()
+                , inputsAnswerOptions: inputAnswerOptionsDict
+            };
+            const formAnswer = new FormAnswer(OptHandler.formAnswer(formAnswerOptions));
+            try {
+                ValidationHandler.validateFormAnswer(formAnswer);
+            } catch (e) {
+                expect(e.validationDict["23"]).to.be.equal("Input answer must be a int;Number of input answers must be lower than 2");
+                expect(e.validationDict["24"]).to.be.undefined;
+                expect(e.validationDict["25"]).to.be.equal("Input answer must be a float");
+                expect(e.validationDict["26"]).to.be.undefined;
+                expect(e.validationDict["27"]).to.be.equal("Input answer must be a date");
+                expect(e.validationDict["28"]).to.be.undefined;
+                expect(e.validationDict["29"]).to.be.equal("Input answer must be a invalid;Number of input answers must be lower than invalid;Must answer question with id 28 and placement invalid");
+            }
+            done();
+        });
     });
 
+    it("should test when input has sugestion", (done) => {
+
+        const inputAnswerOpt1: InputAnswerOptions = {
+            idInput: 18
+            , placement: 5
+            , value: "Invalid Placement"
+        };
+
+        const inputAnswerOpt2: InputAnswerOptions = {
+            idInput: 19
+            , placement: 1
+            , value: "true"
+        };
+
+        const inputAnswerOpt3: InputAnswerOptions = {
+            idInput: 20
+            , placement: 1
+            , value: "true"
+        };
+
+        const inputAnswerOpt4: InputAnswerOptions = {
+            idInput: 21
+            , placement: 0
+            , value: "true"
+        };
+
+        const inputAnswerOpt5: InputAnswerOptions = {
+            idInput: 22
+            , placement: 0
+            , value: "Answer question 5 form 6"
+        };
+
+        const inputAnswerOptionsDict: InputAnswerOptionsDict = {
+            18: [
+                inputAnswerOpt1
+            ]
+            , 19: [inputAnswerOpt2]
+            , 20: [inputAnswerOpt3]
+            , 21: [inputAnswerOpt4]
+            , 22: [inputAnswerOpt5]
+        };
+
+        dbhandler.form.read(6, (error: Error, form: Form) => {
+            const formAnswerOptions: FormAnswerOptions = {
+                form
+                , timestamp: new Date()
+                , inputsAnswerOptions: inputAnswerOptionsDict
+            };
+            const formAnswer = new FormAnswer(OptHandler.formAnswer(formAnswerOptions));
+            try {
+                ValidationHandler.validateFormAnswer(formAnswer);
+            } catch (e) {
+                expect(e.validationDict["18"]).to.be.equal("Input answer must have a answer");
+                expect(e.validationDict["19"]).to.be.undefined;
+                expect(e.validationDict["20"]).to.be.undefined;
+                expect(e.validationDict["21"]).to.be.undefined;
+                expect(e.validationDict["22"]).to.be.equal("Must answer question with id 18 and placement 2");
+            }
+            done();
+        });
+    });
 });
diff --git a/src/utils/validationHandler.ts b/src/utils/validationHandler.ts
index d04a2d4db0c3359b06fc90c7edb63fa3c4683ae6..85db98349cd54843fcc6c7d02918a1d59b828eaa 100644
--- a/src/utils/validationHandler.ts
+++ b/src/utils/validationHandler.ts
@@ -21,6 +21,7 @@
 
 import { FormAnswer } from "../core/formAnswer";
 import { Input } from "../core/input";
+import { InputAnswer, InputAnswerDict } from "../core/inputAnswer";
 import { ValidationType } from "./enumHandler";
 import { ValidationDict, ValidationError  } from "./validationError";
 
@@ -33,93 +34,220 @@ export class ValidationHandler {
      * Validate a string according given a regex.
      * @param answer - Answer to be validated.
      * @param regex - Regex to validate answer.
-     * @returns - true if answer match regex, else false.
+     * @returns - True if answer match regex, else false.
      */
-    private static validateByRegex(answer: string, regex: string): boolean{
+    private static validateByRegex(answer: string, regex: string): boolean {
         const regexp = new RegExp(regex);
         return regexp.test(answer);
     }
 
     /**
-     * Validate if is null, undefined nor ""
+     * Validate if is null, undefined nor "".
      * @param answer - answer to be validated.
-     * @returns - true if not null, "" nor undefined, else false.
+     * @returns - True if not null, "" nor undefined, else false.
      */
-    private static validateMandatory(answer: string): boolean{
+    private static validateMandatory(answer: string): boolean {
         return ((!answer) === false);
     }
 
     /**
-     * Validate if answer has minimum number of chars
+     * Validate if answer has minimum number of chars.
      * @param answer - Answer to be validated.
      * @param size - Minimum size that answer should have.
-     * @returns - true if has at least Size chars, else false.
+     * @returns - True if has at least Size chars, else false.
      */
-    private static validateMinChar(answer: string, size: string): boolean{
-        return  (answer !== null && answer !== undefined && parseInt(size, 10) <= answer.length);
+    private static validateMinChar(answer: string, size: string): boolean {
+        return (answer !== null && answer !== undefined && parseInt(size, 10) <= answer.length);
     }
 
     /**
-     * Validate if answer has minimum number of chars
+     * Validate if answer has minimum number of chars.
      * @param answer - Answer to be validated.
      * @param size - Maximum size that answer should have.
-     * @returns - true if has at max Size chars, else false.
+     * @returns - True if has at max Size chars, else false.
      */
-    private static validateMaxChar(answer: string, size: string): boolean{
-        return  (answer !== null && answer !== undefined  && parseInt(size, 10) >= answer.length);
+    private static validateMaxChar(answer: string, size: string): boolean {
+        return (answer !== null && answer !== undefined  && parseInt(size, 10) >= answer.length);
     }
 
     /**
-     * Validate if answer has minimum number of chars
+     * Validate if answer is of a determined type.
+     * @param answer - Answer to be validated.
+     * @param type - Type that answer should be.
+     * @returns - True if it is of the determined type, else false.
+     */
+    private static validateTypeOf(answer: string, type: string): boolean {
+        // Using string here to avoid validate validations
+        if (type === "int") {
+            return(!isNaN(parseInt(answer, 10)));
+        } else if (type === "float") {
+            return(!isNaN(parseFloat(answer)));
+        } else if (type === "date") {
+            return((new Date(answer)).toString() !== "Invalid Date");
+        } else {
+            return(false);
+        }
+    }
+
+    /**
+     * Validate if answer has minimum one checkbox checked.
+     * @param input - Input that checkbox belongs to.
+     * @param inputAnswer - Answers to checkbox.
+     * @returns - true if has at minimum one checkbox marked, else false.
+     */
+    private static validateSomeCheckbox(input: Input, inputAnswers: InputAnswerDict): boolean {
+        let result: boolean = false;
+        for (const answer of inputAnswers[input.id]) {
+            if ((answer.value === "true") && this.inputSugestionExists(input, answer.placement)) {
+                result = true;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Validate if a sugestion exists.
+     * @param input - Input that have sugestions to be verified.
+     * @param placement - Value of answer to be verified.
+     * @returns - True if sugestion exists, else false.
+     */
+    private static inputSugestionExists(input: Input, placement: number): boolean {
+        let result: boolean = false;
+        for (const sugestion of input.sugestions) {
+            if (sugestion.placement === placement) {
+                result = true;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Validate if a input has a minimum number of answers.
+     * @param inputAnswers - Dictionary of InputAnswers to be verified.
+     * @param id - Input to be searched.
+     * @param argument - Max number of answers.
+     * @returns - True if has minimum answers, else false.
+     */
+    private static validateMaxAnswers(inputAnswers: InputAnswerDict, id: number, argument: string): boolean {
+        const max: number = parseInt(argument, 10);
+        // Verify if argument is an integer
+        if (!(isNaN(max))) {
+            return (inputAnswers[id].length <= max);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Validate if exists a answer for a dependent input.
+     * @param inputAnswers - Dictionary of InputAnswers to be verified.
+     * @param argument - Placement of the dependent input.
+     * @returns - True if the input was answered, else false.
+     */
+    private static validateDependency(inputAnswers: InputAnswer[], argument: string): boolean {
+        let result: boolean = false;
+        const placement: number = parseInt(argument, 10);
+        if (!(isNaN(placement))) {
+            for (const inputAnswer of inputAnswers) {
+                if (inputAnswer.placement === placement) {
+                    result = (inputAnswer.value === "true");
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Validate if answer has minimum number of chars.
      * @param input - Input to validate answer.
-     * @param answer - Answer of input
+     * @param answer - Answer of input.
      * @returns - A string with all errors.
      */
-    private static validateInput(input: Input, answer: string): string{
+    private static validateInput(input: Input, inputAnswers: InputAnswerDict): string {
         const errors: string[] = [];
-        for ( const validation of input.validation){
+
+        for (const validation of input.validation) {
 
             switch (validation.type) {
+
                 case ValidationType.REGEX:
-                    if (!this.validateByRegex(answer, validation.arguments[0])){
-                        errors.push("RegEx do not match");
+                    for (const answer of inputAnswers[input.id]) {
+                        if (!this.validateByRegex(answer.value, validation.arguments[0])) {
+                            errors.push("RegEx do not match");
+                        }
                     }
                     break;
+
                 case ValidationType.MANDATORY:
-                    if (!(this.validateMandatory(answer))){
-                        errors.push("Input answer is mandatory");
+                    for (const answer of inputAnswers[input.id]) {
+                        if (!(this.validateMandatory(answer.value))) {
+                            errors.push("Input answer is mandatory");
+                        }
                     }
                     break;
+
                 case ValidationType.MAXCHAR:
-                    if (!(this.validateMaxChar(answer, validation.arguments[0]))){
-                        errors.push("Input answer must be lower than " + validation.arguments[0]);
+                    for (const answer of inputAnswers[input.id]) {
+                        if (!(this.validateMaxChar(answer.value, validation.arguments[0]))) {
+                            errors.push("Input answer must be lower than " + validation.arguments[0]);
+                        }
                     }
                     break;
+
                 case ValidationType.MINCHAR:
-                    if (!(this.validateMinChar(answer, validation.arguments[0]))){
-                        errors.push("Input answer must be greater than " + validation.arguments[0]);
+                    for (const answer of inputAnswers[input.id]) {
+                        if (!(this.validateMinChar(answer.value, validation.arguments[0]))) {
+                            errors.push("Input answer must be greater than " + validation.arguments[0]);
+                        }
                     }
                     break;
-            }
 
+                case ValidationType.TYPEOF:
+                    for (const answer of inputAnswers[input.id]) {
+                        if (!(this.validateTypeOf(answer.value, validation.arguments[0]))) {
+                            errors.push("Input answer must be a " + validation.arguments[0]) + " type";
+                        }
+                    }
+                    break;
+
+                case ValidationType.SOMECHECKBOX:
+                    if (!(this.validateSomeCheckbox(input, inputAnswers))) {
+                        errors.push("Input answer must have a answer");
+                    }
+                    break;
+
+                case ValidationType.MAXANSWERS:
+                    if (!(this.validateMaxAnswers(inputAnswers, input.id, validation.arguments[0]))) {
+                        errors.push("Number of input answers must be lower than " + validation.arguments[0]);
+                    }
+                    break;
+
+                case ValidationType.DEPENDENCY:
+                    const id: number = parseInt(validation.arguments[0], 10);
+                    if (!(isNaN(id)) && !(this.validateDependency(inputAnswers[id], validation.arguments[1]))) {
+                        errors.push("Must answer question with id " + validation.arguments[0] + " and placement " + validation.arguments[1]);
+                    }
+                    break;
+            }
         }
-        return errors.join(";");
 
+        return errors.join(";");
     }
 
-    public static validateFormAnswer(formAnswer: FormAnswer): void{
+    /**
+     * Validate if form answer is valid.
+     * @param formAnswer - FormAnswer to be validated.
+     */
+    public static validateFormAnswer(formAnswer: FormAnswer): void {
         const errorsDict: ValidationDict = {};
-
-        for ( const input of formAnswer.form.inputs){
-            for (const answer of formAnswer.inputAnswers[input.id]){
-                const error: string =  this.validateInput(input, answer.value);
-                if (error !== "" && error !== undefined){
-                    errorsDict[input.id] = error;
-                }
+        for (const input of formAnswer.form.inputs) {
+            const error: string = this.validateInput(input, formAnswer.inputAnswers);
+            if (error !== "" && error !== undefined) {
+                errorsDict[input.id] = error;
             }
         }
 
-        if ( Object.keys(errorsDict).length > 0){
+        if ( Object.keys(errorsDict).length > 0) {
             throw new ValidationError(errorsDict, "Validation Error");
         }
     }