diff --git a/bindings/Makefile b/bindings/Makefile
index 2e11971aaeca63b90a39cc15b772436ca75f74ce..f166b210bb9e94e3bc156b2e299c2160c8488951 100644
--- a/bindings/Makefile
+++ b/bindings/Makefile
@@ -11,10 +11,14 @@ SAMPLE_M68K = $(TMPDIR)/sample_m68k
 SAMPLE_SPARC = $(TMPDIR)/sample_sparc
 SAMPLE_X86 = $(TMPDIR)/sample_x86
 
-.PHONY: all expected python
+.PHONY: all expected python rust go nodejs ruby
 
 all:
 	cd python && $(MAKE) gen_const
+	python const_generator.py rust
+	python const_generator.py go
+	python const_generator.py python
+	python const_generator.py ruby
 	python const_generator.py nodejs
 	cd ruby && $(MAKE) gen_const
 
@@ -42,6 +46,18 @@ python: FORCE
 	python python/sample_x86.py > $(SAMPLE_X86)_o
 	$(MAKE) sample_diff
 
+ruby: FORCE
+	cd ruby && $(MAKE)
+
+nodejs: FORCE
+	cd nodejs && $(MAKE)
+
+rust: FORCE
+	cd rust && $(MAKE)
+
+go: FORCE
+	cd go && $(MAKE)
+
 sample_diff: FORCE
 	$(DIFF) $(SAMPLE_ARM)_e $(SAMPLE_ARM)_o
 	$(DIFF) $(SAMPLE_ARM64)_e $(SAMPLE_ARM64)_o
@@ -53,8 +69,16 @@ sample_diff: FORCE
 clean:
 	rm -rf $(TMPDIR)
 	cd python && $(MAKE) clean
+	cd rust && $(MAKE) clean
+	cd go && $(MAKE) clean
+	cd nodejs && $(MAKE) clean
+	cd ruby && $(MAKE) clean
 
 check:
 	make -C python check
+	make -C rust check
+	make -C go check
+	make -C nodejs check
+	make -C ruby check
 
 FORCE:
diff --git a/bindings/const_generator.py b/bindings/const_generator.py
index beababa15c820823497ede5b59558bd82f5616cd..c8f1f43580139a1cd20072b62781c3ee541aae7c 100644
--- a/bindings/const_generator.py
+++ b/bindings/const_generator.py
@@ -10,11 +10,151 @@ ks_err_val = { 'KS_ERR_ASM': '128', 'KS_ERR_ASM_ARCH': '512' }
 
 include = [ 'arm.h', 'arm64.h', 'mips.h', 'x86.h', 'sparc.h', 'ppc.h', 'systemz.h', 'hexagon.h', 'keystone.h' ]
 
+def CamelCase(s):
+    # return re.sub(r'(\w)+\_?', lambda m:m.group(0).capitalize(), s)
+    return ''.join(''.join([w[0].upper(), w[1:].lower()]) for w in s.split('_'))
+
 template = {
+    'rust': {
+            'header': "// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [%s_const.rs]\nextern crate libc;\n\n",
+            'footer': "",
+            # prefixes for constant filenames of all archs - case sensitive
+            'arm.h': 'keystone',
+            'arm64.h': 'keystone',
+            'mips.h': 'keystone',
+            'x86.h': 'keystone',
+            'sparc.h': 'keystone',
+            'systemz.h': 'keystone',
+            'ppc.h': 'keystone',
+            'hexagon.h': 'keystone',
+            'keystone.h': 'keystone',
+            'comment_open': '/*',
+            'comment_close': '*/',
+            'out_file': './rust/src/%s_const.rs',
+            'rules': [
+                {
+                    'regex': r'(API|ARCH)_.*',
+                    'pre': '\n',
+                    'line_format': 'pub const KS_{0} : u32 = {1};\n',
+                    'fn': (lambda x: x),
+                    'post': '\n',
+                },
+                {   'regex': r'MODE_.*',
+                    'pre': 'bitflags! {\n\tpub flags Mode : u32 {\n',
+                    'line_format': '\t\tconst {0} = {1},\n',
+                    'fn': (lambda x: x),
+                    'post': '\t}\n}\n',
+                },
+                {
+                    'regex': r'ARCH_.*',
+                    'pre': '#[derive(Debug, PartialEq, Clone, Copy)]\n' + 
+                            'pub enum Arch {\n',
+                    'line_format': '\t{0},\n',
+                    'fn': (lambda x: '_'.join(x.split('_')[1:])),
+                    'post': '}\n\n',
+                },
+                {   'regex': r'ARCH_.*',
+                    'pre': 'impl Arch {\n\t#[inline]\n\tpub fn val(&self) -> u32 {\n\t\tmatch *self {\n',
+                    'line_format': '\t\t\tArch::{0} => {1},\n',
+                    'fn': (lambda x: '_'.join(x.split('_')[1:])),
+                    'post': '\t\t}\n\t}\n}\n',
+                },
+                {
+                    'regex': r'OPT_([A-Z]+)$',
+                    'pre': '#[derive(Debug, PartialEq, Clone, Copy)]\n' + 
+                            'pub enum OptionType {\n',
+                    'line_format': '\t{0},\n',
+                    'fn': (lambda x: '_'.join(x.split('_')[1:])),
+                    'post': '\tMAX,\n' +
+                            '}\n',
+                },
+                {   
+                    'regex': r'OPT_([A-Z]+)$',
+                    'pre': 'impl OptionType {\n\t#[inline]\n\tpub fn val(&self) -> u32 {\n\t\tmatch *self {\n',
+                    'line_format': '\t\t\tOptionType::{0} => {1},\n',
+                    'fn': (lambda x: '_'.join(x.split('_')[1:])),
+                    'post': '\t\t\tOptionType::MAX => 99\n' +
+                            '\t\t}\n\t}\n}\n',
+                },
+                {
+                    'regex': r'OPT_([A-Z]+\_)+[A-Z]+',
+                    'pre': 'bitflags! {\n\tpub flags OptionValue : libc::size_t {\n',
+                    'line_format': '\t\tconst {0} = {1},\n',
+                    'fn': (lambda x: x),
+                    'post': '\t}\n}\n',
+                },
+                {
+                    'regex': r'ERR_.*',
+                    'pre': 'bitflags! {\n\tpub flags Error : u32 {\n',
+                    'line_format': '\t\tconst {0} = {1},\n',
+                    'fn': (lambda x: x),
+                    'post': '\t}\n}\n',
+                },
+            ],
+    },
+    'go': {
+            'header': "package keystone\n// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [%s_const.go]\n\n",
+            'footer': "",
+            # prefixes for constant filenames of all archs - case sensitive
+            'arm.h': 'arm',
+            'arm64.h': 'arm64',
+            'mips.h': 'mips',
+            'x86.h': 'x86',
+            'sparc.h': 'sparc',
+            'systemz.h': 'systemz',
+            'ppc.h': 'ppc',
+            'hexagon.h': 'hexagon',
+            'keystone.h': 'keystone',
+            'comment_open': '/*',
+            'comment_close': '*/',
+            'out_file': './go/keystone/%s_const.go',
+            'rules': [
+                {
+                    'regex': r'(API)_.*',
+                    'pre': 'const (\n',
+                    'line_format': '\t\t{0} = {1}\n',
+                    'fn': (lambda x: x),
+                    'post': ')\n',
+                },
+                {   'regex': r'MODE_.*',
+                    'pre': 'const (\n',
+                    'line_format': '\t\t{0} Mode = {1}\n',
+                    'fn': (lambda x: x),
+                    'post': ')\n',
+                },
+                {
+                    'regex': r'ARCH_.*',
+                    'pre': 'const (\n',
+                    'line_format': '\t\t{0} Architecture = {1}\n',
+                    'fn': (lambda x: x),
+                    'post': ')\n',
+                },
+                {
+                    'regex': r'OPT_([A-Z]+)$',
+                    'pre': 'const (\n',
+                    'line_format': '\t\t{0} OptionType = {1}\n',
+                    'fn': (lambda x: x),
+                    'post': ')\n',
+                },
+                {
+                    'regex': r'OPT_([A-Z]+\_)+[A-Z]+',
+                    'pre': 'const (\n',
+                    'line_format': '\t\t{0} OptionValue = {1}\n',
+                    'fn': (lambda x: x),
+                    'post': ')\n',
+                },
+                {
+                    'regex': r'ERR_.*',
+                    'pre': 'const (\n',
+                    'line_format': '\t\t{0} Error = {1}\n',
+                    'fn': (lambda x: x),
+                    'post': ')\n',
+                },
+            ]
+    },
     'python': {
             'header': "# For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [%s_const.py]\n",
             'footer': "",
-            'line_format': 'KS_%s = %s\n',
             'out_file': './python/keystone/%s_const.py',
             # prefixes for constant filenames of all archs - case sensitive
             'arm.h': 'arm',
@@ -28,11 +168,17 @@ template = {
             'keystone.h': 'keystone',
             'comment_open': '#',
             'comment_close': '',
+            'rules': [
+                {
+                    'regex': r'.*',
+                    'line_format': 'KS_{0} = {1}\n',
+                    'fn': (lambda x: x),
+                },
+            ]
         },
     'nodejs': {
             'header': "// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [%s_const.js]\n",
             'footer': "",
-            'line_format': 'module.exports.%s = %s\n',
             'out_file': './nodejs/consts/%s.js',
             # prefixes for constant filenames of all archs - case sensitive
             'arm.h': 'arm',
@@ -46,11 +192,17 @@ template = {
             'keystone.h': 'keystone',
             'comment_open': '//',
             'comment_close': '',
+            'rules': [
+                {
+                    'regex': r'.*',
+                    'line_format': 'module.exports.{0} = {1}\n',
+                    'fn': (lambda x: x),
+                },
+            ]
     },
     'ruby': {
             'header': "# For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [%s_const.rb]\n\nmodule Keystone\n",
             'footer': "end",
-            'line_format': '\tKS_%s = %s\n',
             'out_file': './ruby/keystone_gem/lib/keystone/%s_const.rb',
             # prefixes for constant filenames of all archs - case sensitive
             'arm.h': 'arm',
@@ -64,7 +216,14 @@ template = {
             'keystone.h': 'keystone',
             'comment_open': '#',
             'comment_close': '',
-        },
+            'rules': [
+                {
+                    'regex': r'.*',
+                    'line_format': '\tKS_{0} = {1}\n',
+                    'fn': (lambda x: x),
+                },
+            ]
+    },
 }
 
 # markup for comments to be added to autogen files
@@ -72,15 +231,18 @@ MARKUP = '//>'
 
 def gen(lang):
     global include, INCL_DIR
+
+    consts = {}
+
     templ = template[lang]
     for target in include:
         prefix = templ[target]
-        outfile = open(templ['out_file'] %(prefix), 'wb')   # open as binary prevents windows newlines
-        outfile.write((templ['header'] % (prefix)).encode("utf-8"))
         if target == 'keystone.h':
-            prefix = ''
+            prefix = 'keystone'
         lines = open(os.path.join(INCL_DIR, target)).readlines()
 
+        consts[prefix] = []
+
         previous = {}
         count = 0
         for line in lines:
@@ -141,14 +303,45 @@ def gen(lang):
                             rhs = ks_err_val[rhs]
 
                     lhs_strip = re.sub(r'^KS_', '', lhs)
+                    consts[prefix].append((lhs_strip, rhs))
+
                     count = int(rhs) + 1
-                    if (count == 1):
-                        outfile.write(("\n").encode("utf-8"))
 
-                    outfile.write((templ['line_format'] % (lhs_strip, rhs)).encode("utf-8"))
                     previous[lhs] = str(rhs)
 
-        outfile.write((templ['footer']).encode("utf-8"))
+
+    rules = templ['rules']
+
+    for prefix in consts.keys():
+        outfile = open(templ['out_file'] % prefix, 'wb')   # open as binary prevents windows newlines
+        outfile.write (templ['header'] % prefix)
+
+        for rule in rules:
+            regex = rule['regex']
+
+            consts2 = []
+            for const in consts.get(prefix):
+                if not (re.match(regex, const[0])):
+                    continue
+
+                consts2.append(const)
+
+            if len(consts2) == 0:
+                continue
+
+            if rule.get('pre'):
+                outfile.write (rule.get('pre'))
+
+            for const in consts2:
+                lhs_strip = const[0]
+                rhs = const[1]
+                outfile.write(rule['line_format'].format(rule['fn'](lhs_strip), rhs, lhs_strip).encode("utf-8"))
+
+            if rule.get('post'):
+                outfile.write (rule.get('post'))
+                outfile.write ('\n')
+
+        outfile.write (templ['footer'])
         outfile.close()
 
 def main():
diff --git a/bindings/go/Makefile b/bindings/go/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..7dc07269ae15badb30498c88173f0aed4caef495
--- /dev/null
+++ b/bindings/go/Makefile
@@ -0,0 +1,20 @@
+# Python binding for Keystone engine. Nguyen Anh Quynh <aquynh@gmail.com>
+
+ifndef BUILDDIR
+OBJDIR = ./build
+else
+OBJDIR = $(abspath $(BUILDDIR))/obj/bindings/go
+endif
+
+.PHONY: gen_const install clean
+
+gen_const:
+	cd .. && python const_generator.py go
+
+install:
+	cd keystone && go build
+
+clean:
+
+check:
+	cd keystone && go test
diff --git a/bindings/go/README.md b/bindings/go/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ca289f858d2d1ba0e70d71f1f1f968f5c03b6fce
--- /dev/null
+++ b/bindings/go/README.md
@@ -0,0 +1,45 @@
+# keystone 
+Go bindings for the [keystone](http://www.keystone-engine.org/) engine.
+
+```go
+package main
+
+import (
+        "fmt"
+        "os"
+
+        keystone "github.com/keystone-engine/beta/bindings/go/keystone"
+)
+
+func main() {
+        assembly := os.Args[1]
+
+        if ks, err := keystone.New(keystone.ArchitectureX86, keystone.Mode32); err != nil {
+                panic(err)
+        } else {
+                defer ks.Close()
+
+                if err := ks.Option(keystone.OptionSyntax, keystone.OptionSyntaxIntel); err != nil {
+                        panic(fmt.Errorf("Could not set syntax option to intel"))
+                }
+
+                if insn, _, ok := ks.Assemble(assembly, 0); !ok {
+                        panic(fmt.Errorf("Could not assemble instruction"))
+                } else {
+                        fmt.Printf("%s: [%x]", assembly, insn)
+                }
+        }
+}
+```
+
+## Installation
+
+## Notes
+
+## Contributing
+
+Contributors:
+- Remco Verhoef (@remco_verhoef)
+
+Special thanks to:
+- Sébastien Duquette (@ekse) for his [unicorn-rs](https://github.com/ekse/unicorn-rs) binding
diff --git a/bindings/go/keystone/arm64_const.go b/bindings/go/keystone/arm64_const.go
new file mode 100644
index 0000000000000000000000000000000000000000..004af4da2ae6a2dff125f3aceac07bb403d0b709
--- /dev/null
+++ b/bindings/go/keystone/arm64_const.go
@@ -0,0 +1,9 @@
+package keystone
+// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [arm64_const.go]
+
+const (
+		ERR_ASM_ARM64_INVALIDOPERAND Error = 512
+		ERR_ASM_ARM64_MISSINGFEATURE Error = 513
+		ERR_ASM_ARM64_MNEMONICFAIL Error = 514
+)
+
diff --git a/bindings/go/keystone/arm_const.go b/bindings/go/keystone/arm_const.go
new file mode 100644
index 0000000000000000000000000000000000000000..90d3efe0388fe0a7f9021829140316030d0e938e
--- /dev/null
+++ b/bindings/go/keystone/arm_const.go
@@ -0,0 +1,9 @@
+package keystone
+// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [arm_const.go]
+
+const (
+		ERR_ASM_ARM_INVALIDOPERAND Error = 512
+		ERR_ASM_ARM_MISSINGFEATURE Error = 513
+		ERR_ASM_ARM_MNEMONICFAIL Error = 514
+)
+
diff --git a/bindings/go/keystone/hexagon_const.go b/bindings/go/keystone/hexagon_const.go
new file mode 100644
index 0000000000000000000000000000000000000000..a0fc92d6f3e5f8d4e0b4b9e235bf24a9ba9e3014
--- /dev/null
+++ b/bindings/go/keystone/hexagon_const.go
@@ -0,0 +1,9 @@
+package keystone
+// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [hexagon_const.go]
+
+const (
+		ERR_ASM_HEXAGON_INVALIDOPERAND Error = 512
+		ERR_ASM_HEXAGON_MISSINGFEATURE Error = 513
+		ERR_ASM_HEXAGON_MNEMONICFAIL Error = 514
+)
+
diff --git a/bindings/go/keystone/keystone-binding.c b/bindings/go/keystone/keystone-binding.c
new file mode 100644
index 0000000000000000000000000000000000000000..8498366bbe3dc35e09d23c51f908ca1dd4e16a0d
--- /dev/null
+++ b/bindings/go/keystone/keystone-binding.c
@@ -0,0 +1,5 @@
+// Copyright © 2015, Keylocker. All rights reserved.
+
+// +build darwin,linux,cgo
+
+#include <keystone.h>
diff --git a/bindings/go/keystone/keystone-binding.go b/bindings/go/keystone/keystone-binding.go
new file mode 100644
index 0000000000000000000000000000000000000000..a6b20ab2991073a3dd8349688d05775091c34e66
--- /dev/null
+++ b/bindings/go/keystone/keystone-binding.go
@@ -0,0 +1,65 @@
+/* Keystone Assembler Engine (www.keystone-engine.org) */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2016 */
+/* Golang bindings by Remco Verhoef <remco@dutchcoders.io>, 2016 */
+
+// +build darwin,linux,cgo
+package keystone
+
+// #cgo linux LDFLAGS:-lkeystone
+// #include "keystone-binding.h"
+// #include "keystone.h"
+import "C"
+import "unsafe"
+
+func ks_version() (uint, uint) {
+	major := C.uint(0)
+	minor := C.uint(0)
+	C.ks_version(&major, &minor)
+	return uint(major), uint(minor)
+}
+
+func ks_arch_supported(a Architecture) bool {
+	return bool(C.ks_arch_supported((C.ks_arch)(a)))
+}
+
+func ks_open(a Architecture, m Mode, engine **C.ks_engine) error {
+	if err := C.ks_open((C.ks_arch)(a), (C.int)(m), (**C.ks_engine)(unsafe.Pointer(engine))); err != 0 {
+		return Error(err)
+	}
+
+	return nil
+}
+
+func ks_option(engine *C.ks_engine, type_ OptionType, value OptionValue) error {
+	if err := C.ks_option(engine, C.ks_opt_type(type_), C.size_t(value)); err != 0 {
+		return Error(err)
+	}
+	return nil
+}
+
+func ks_errno(engine *C.ks_engine) error {
+	if err := C.ks_errno(engine); err != 0 {
+		return Error(err)
+	}
+	return nil
+}
+
+func ks_asm(engine *C.ks_engine, str string, address uint64, encoding *[]byte, stat_count *uint64) bool {
+	cstr := C.CString(str)
+	defer C.free(unsafe.Pointer(cstr))
+
+	var p_insn unsafe.Pointer
+	defer C.free(unsafe.Pointer(p_insn))
+
+	l_insn := C.size_t(0)
+	err := C.ks_asm(engine, cstr, C.uint64_t(address), (**C.uchar)(unsafe.Pointer(&p_insn)), &l_insn, (*C.size_t)(stat_count))
+	*encoding = C.GoBytes(p_insn, C.int(l_insn))
+	return err == 0
+}
+
+func ks_close(engine *C.ks_engine) error {
+	if err := C.ks_close(engine); err != 0 {
+		return Error(err)
+	}
+	return nil
+}
diff --git a/bindings/go/keystone/keystone-binding.h b/bindings/go/keystone/keystone-binding.h
new file mode 100644
index 0000000000000000000000000000000000000000..3bbc3f1797fded539a7ad08ea541678af3e1fcba
--- /dev/null
+++ b/bindings/go/keystone/keystone-binding.h
@@ -0,0 +1,7 @@
+/* Keystone Assembler Engine (www.keystone-engine.org) */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2016 */
+/* Golang bindings by Remco Verhoef <remco@dutchcoders.io>, 2016 */
+
+// #include <keystone.h>
+
+
diff --git a/bindings/go/keystone/keystone.go b/bindings/go/keystone/keystone.go
new file mode 100644
index 0000000000000000000000000000000000000000..18305c5e5d38cc8ac8ae219fd93769f0e4262812
--- /dev/null
+++ b/bindings/go/keystone/keystone.go
@@ -0,0 +1,67 @@
+/* Keystone Assembler Engine (www.keystone-engine.org) */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2016 */
+/* Golang bindings by Remco Verhoef <remco@dutchcoders.io>, 2016 */
+
+package keystone
+
+// #include "keystone.h"
+import "C"
+
+type Architecture uint
+
+type Mode uint
+
+type OptionType uint
+
+type OptionValue uint
+
+type Error uint32
+
+func (e Error) Error() string {
+	s := C.ks_strerror((C.ks_err)(e))
+	return C.GoString(s)
+}
+
+func (a Architecture) Supported() bool {
+	return ks_arch_supported(a)
+}
+
+func Version() (uint, uint) {
+	return ks_version()
+}
+
+type Keystone struct {
+	engine *C.ks_engine
+}
+
+func New(a Architecture, m Mode) (*Keystone, error) {
+	ks := &Keystone{}
+	if err := ks_open(a, m, &ks.engine); err != nil {
+		return nil, err
+	} else {
+		return ks, nil
+	}
+}
+
+func (ks *Keystone) LastError() error {
+	return ks_errno(ks.engine)
+}
+
+func (ks *Keystone) Option(type_ OptionType, value OptionValue) error {
+	if err := ks_option(ks.engine, type_, value); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (ks *Keystone) Assemble(str string, address uint64) ([]byte, uint64, bool) {
+	encoding := []byte{}
+	stat_count := uint64(0)
+	ok := ks_asm(ks.engine, str, address, &encoding, &stat_count)
+	return encoding, stat_count, ok
+}
+
+func (ks *Keystone) Close() error {
+	return ks_close(ks.engine)
+}
diff --git a/bindings/go/keystone/keystone_const.go b/bindings/go/keystone/keystone_const.go
new file mode 100644
index 0000000000000000000000000000000000000000..5a3f530ab2b3b639a44f45040ad27b22b95ba3db
--- /dev/null
+++ b/bindings/go/keystone/keystone_const.go
@@ -0,0 +1,101 @@
+package keystone
+// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [keystone_const.go]
+
+const (
+		API_MAJOR = 1
+		API_MINOR = 0
+)
+
+const (
+		MODE_LITTLE_ENDIAN Mode = 0
+		MODE_BIG_ENDIAN Mode = 1073741824
+		MODE_ARM Mode = 1
+		MODE_THUMB Mode = 16
+		MODE_V8 Mode = 64
+		MODE_MICRO Mode = 16
+		MODE_MIPS3 Mode = 32
+		MODE_MIPS32R6 Mode = 64
+		MODE_MIPS32 Mode = 4
+		MODE_MIPS64 Mode = 8
+		MODE_16 Mode = 2
+		MODE_32 Mode = 4
+		MODE_64 Mode = 8
+		MODE_PPC32 Mode = 4
+		MODE_PPC64 Mode = 8
+		MODE_QPX Mode = 16
+		MODE_SPARC32 Mode = 4
+		MODE_SPARC64 Mode = 8
+		MODE_V9 Mode = 16
+)
+
+const (
+		ARCH_ARM Architecture = 1
+		ARCH_ARM64 Architecture = 2
+		ARCH_MIPS Architecture = 3
+		ARCH_X86 Architecture = 4
+		ARCH_PPC Architecture = 5
+		ARCH_SPARC Architecture = 6
+		ARCH_SYSTEMZ Architecture = 7
+		ARCH_HEXAGON Architecture = 8
+		ARCH_MAX Architecture = 9
+)
+
+const (
+		OPT_SYNTAX OptionType = 1
+)
+
+const (
+		OPT_SYNTAX_INTEL OptionValue = 1
+		OPT_SYNTAX_ATT OptionValue = 2
+		OPT_SYNTAX_NASM OptionValue = 4
+		OPT_SYNTAX_MASM OptionValue = 8
+		OPT_SYNTAX_GAS OptionValue = 16
+)
+
+const (
+		ERR_ASM Error = 128
+		ERR_ASM_ARCH Error = 512
+		ERR_OK Error = 0
+		ERR_NOMEM Error = 1
+		ERR_ARCH Error = 2
+		ERR_HANDLE Error = 3
+		ERR_MODE Error = 4
+		ERR_VERSION Error = 5
+		ERR_OPT_INVALID Error = 6
+		ERR_ASM_EXPR_TOKEN Error = 128
+		ERR_ASM_DIRECTIVE_VALUE_RANGE Error = 129
+		ERR_ASM_DIRECTIVE_ID Error = 130
+		ERR_ASM_DIRECTIVE_TOKEN Error = 131
+		ERR_ASM_DIRECTIVE_STR Error = 132
+		ERR_ASM_DIRECTIVE_COMMA Error = 133
+		ERR_ASM_DIRECTIVE_RELOC_NAME Error = 134
+		ERR_ASM_DIRECTIVE_RELOC_TOKEN Error = 135
+		ERR_ASM_DIRECTIVE_FPOINT Error = 136
+		ERR_ASM_DIRECTIVE_UNKNOWN Error = 137
+		ERR_ASM_VARIANT_INVALID Error = 138
+		ERR_ASM_DIRECTIVE_EQU Error = 139
+		ERR_ASM_EXPR_BRACKET Error = 140
+		ERR_ASM_SYMBOL_MODIFIER Error = 141
+		ERR_ASM_SYMBOL_REDEFINED Error = 142
+		ERR_ASM_SYMBOL_MISSING Error = 143
+		ERR_ASM_RPAREN Error = 144
+		ERR_ASM_STAT_TOKEN Error = 145
+		ERR_ASM_UNSUPPORTED Error = 146
+		ERR_ASM_MACRO_TOKEN Error = 147
+		ERR_ASM_MACRO_PAREN Error = 148
+		ERR_ASM_MACRO_EQU Error = 149
+		ERR_ASM_MACRO_ARGS Error = 150
+		ERR_ASM_MACRO_LEVELS_EXCEED Error = 151
+		ERR_ASM_MACRO_STR Error = 152
+		ERR_ASM_ESC_BACKSLASH Error = 153
+		ERR_ASM_ESC_OCTAL Error = 154
+		ERR_ASM_ESC_SEQUENCE Error = 155
+		ERR_ASM_ESC_STR Error = 156
+		ERR_ASM_TOKEN_INVALID Error = 157
+		ERR_ASM_INSN_UNSUPPORTED Error = 158
+		ERR_ASM_FIXUP_INVALID Error = 159
+		ERR_ASM_INVALIDOPERAND Error = 512
+		ERR_ASM_MISSINGFEATURE Error = 513
+		ERR_ASM_MNEMONICFAIL Error = 514
+)
+
diff --git a/bindings/go/keystone/keystone_test.go b/bindings/go/keystone/keystone_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..0f18997a1d38c120f4263930b34725610dad2d29
--- /dev/null
+++ b/bindings/go/keystone/keystone_test.go
@@ -0,0 +1,66 @@
+/* Keystone Assembler Engine (www.keystone-engine.org) */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2016 */
+/* Golang bindings by Remco Verhoef <remco@dutchcoders.io>, 2016 */
+
+package keystone
+
+import (
+	"fmt"
+	"reflect"
+	"testing"
+)
+
+func TestVersion(t *testing.T) {
+	major, minor := Version()
+	if major == API_MAJOR && minor == API_MINOR {
+	} else {
+		t.Error(fmt.Errorf("Unexpected version: got %d.%d expected %d.%d", major, minor, 1, 0))
+	}
+}
+
+func TestArchitectureSupported(t *testing.T) {
+	if !ARCH_ARM.Supported() {
+		t.Error(fmt.Errorf("ARM not supported"))
+	}
+}
+
+type Test struct {
+	Architecture   Architecture
+	Mode           Mode
+	Address        uint64
+	Assembly       string
+	ExpectedResult []byte
+}
+
+type Syntax struct {
+	Syntax OptionValue
+	Tests  []Test
+}
+
+var tests = []Syntax{
+	Syntax{
+		OPT_SYNTAX_INTEL, []Test{
+			Test{ARCH_X86, MODE_32 | MODE_LITTLE_ENDIAN, 0, "mov ah, al", []byte{0x88, 0xc4}},
+		},
+	},
+}
+
+func TestRun(t *testing.T) {
+	for _, st := range tests {
+		for _, tr := range st.Tests {
+			if ks, err := New(tr.Architecture, tr.Mode); err != nil {
+				t.Error(err)
+			} else {
+				defer ks.Close()
+
+				if err := ks.Option(OPT_SYNTAX, st.Syntax); err != nil {
+					t.Error(fmt.Errorf("Could not set syntax option to intel"))
+				} else if insn, _, ok := ks.Assemble(tr.Assembly, tr.Address); !ok {
+					t.Error(fmt.Errorf("Could not assemble instruction"))
+				} else if !reflect.DeepEqual(insn, tr.ExpectedResult) {
+					t.Error(fmt.Errorf("Not expected result: expected %#v got %#v", tr.ExpectedResult, insn))
+				}
+			}
+		}
+	}
+}
diff --git a/bindings/go/keystone/mips_const.go b/bindings/go/keystone/mips_const.go
new file mode 100644
index 0000000000000000000000000000000000000000..ffa9bcedacb3b14fdd906c85f380d3645bb257c7
--- /dev/null
+++ b/bindings/go/keystone/mips_const.go
@@ -0,0 +1,9 @@
+package keystone
+// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [mips_const.go]
+
+const (
+		ERR_ASM_MIPS_INVALIDOPERAND Error = 512
+		ERR_ASM_MIPS_MISSINGFEATURE Error = 513
+		ERR_ASM_MIPS_MNEMONICFAIL Error = 514
+)
+
diff --git a/bindings/go/keystone/ppc_const.go b/bindings/go/keystone/ppc_const.go
new file mode 100644
index 0000000000000000000000000000000000000000..995c9f059cf55823d1ebdcfb50e4ae4c170766bb
--- /dev/null
+++ b/bindings/go/keystone/ppc_const.go
@@ -0,0 +1,9 @@
+package keystone
+// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [ppc_const.go]
+
+const (
+		ERR_ASM_PPC_INVALIDOPERAND Error = 512
+		ERR_ASM_PPC_MISSINGFEATURE Error = 513
+		ERR_ASM_PPC_MNEMONICFAIL Error = 514
+)
+
diff --git a/bindings/go/keystone/samples/main.go b/bindings/go/keystone/samples/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..567fd14670dea22dd4a555af70386d69e3fcc319
--- /dev/null
+++ b/bindings/go/keystone/samples/main.go
@@ -0,0 +1,32 @@
+/* Keystone Assembler Engine (www.keystone-engine.org) */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2016 */
+/* Golang bindings by Remco Verhoef <remco@dutchcoders.io>, 2016 */
+
+package main
+
+import (
+	"fmt"
+	"os"
+
+	keystone "github.com/keystone-engine/beta/bindings/go/keystone"
+)
+
+func main() {
+	assembly := os.Args[1]
+
+	if ks, err := keystone.New(keystone.ArchitectureX86, keystone.Mode32); err != nil {
+		panic(err)
+	} else {
+		defer ks.Close()
+
+		if err := ks.Option(keystone.OptionSyntax, keystone.OptionSyntaxIntel); err != nil {
+			panic(fmt.Errorf("Could not set syntax option to intel"))
+		}
+
+		if insn, _, ok := ks.Assemble(assembly, 0); !ok {
+			panic(fmt.Errorf("Could not assemble instruction"))
+		} else {
+			fmt.Printf("%s: [%x]", assembly, insn)
+		}
+	}
+}
diff --git a/bindings/go/keystone/sparc_const.go b/bindings/go/keystone/sparc_const.go
new file mode 100644
index 0000000000000000000000000000000000000000..0852618c1d0f3bc77214fdef01bb091f7682ca28
--- /dev/null
+++ b/bindings/go/keystone/sparc_const.go
@@ -0,0 +1,9 @@
+package keystone
+// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [sparc_const.go]
+
+const (
+		ERR_ASM_SPARC_INVALIDOPERAND Error = 512
+		ERR_ASM_SPARC_MISSINGFEATURE Error = 513
+		ERR_ASM_SPARC_MNEMONICFAIL Error = 514
+)
+
diff --git a/bindings/go/keystone/systemz_const.go b/bindings/go/keystone/systemz_const.go
new file mode 100644
index 0000000000000000000000000000000000000000..f33c772efc1a5c169dc408fcca6d53da9ebf55d5
--- /dev/null
+++ b/bindings/go/keystone/systemz_const.go
@@ -0,0 +1,9 @@
+package keystone
+// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [systemz_const.go]
+
+const (
+		ERR_ASM_SYSTEMZ_INVALIDOPERAND Error = 512
+		ERR_ASM_SYSTEMZ_MISSINGFEATURE Error = 513
+		ERR_ASM_SYSTEMZ_MNEMONICFAIL Error = 514
+)
+
diff --git a/bindings/go/keystone/x86_const.go b/bindings/go/keystone/x86_const.go
new file mode 100644
index 0000000000000000000000000000000000000000..5e5ccef6eb002f80098b785def2676c574eedc07
--- /dev/null
+++ b/bindings/go/keystone/x86_const.go
@@ -0,0 +1,9 @@
+package keystone
+// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [x86_const.go]
+
+const (
+		ERR_ASM_X86_INVALIDOPERAND Error = 512
+		ERR_ASM_X86_MISSINGFEATURE Error = 513
+		ERR_ASM_X86_MNEMONICFAIL Error = 514
+)
+
diff --git a/bindings/nodejs/Makefile b/bindings/nodejs/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..188296ca4087d5e2286975e5b6723788f0b30452
--- /dev/null
+++ b/bindings/nodejs/Makefile
@@ -0,0 +1,21 @@
+# Python binding for Keystone engine. Nguyen Anh Quynh <aquynh@gmail.com>
+
+ifndef BUILDDIR
+OBJDIR = ./build
+else
+OBJDIR = $(abspath $(BUILDDIR))/obj/bindings/nodejs
+endif
+
+.PHONY: gen_const install clean
+
+gen_const:
+	cd .. && python const_generator.py nodejs
+
+install:
+	npm install ./
+
+clean:
+
+check:
+	node sample.js
+
diff --git a/bindings/nodejs/consts/keystone.js b/bindings/nodejs/consts/keystone.js
index 6b5967b508a7c392bb1346d11fa3d4605c00d6bd..ee0b5308f73c3d8dea4ce80ed34d4d06cddf1220 100644
--- a/bindings/nodejs/consts/keystone.js
+++ b/bindings/nodejs/consts/keystone.js
@@ -1,6 +1,5 @@
 // For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [keystone_const.js]
 module.exports.API_MAJOR = 1
-
 module.exports.API_MINOR = 0
 module.exports.ARCH_ARM = 1
 module.exports.ARCH_ARM64 = 2
@@ -11,7 +10,6 @@ module.exports.ARCH_SPARC = 6
 module.exports.ARCH_SYSTEMZ = 7
 module.exports.ARCH_HEXAGON = 8
 module.exports.ARCH_MAX = 9
-
 module.exports.MODE_LITTLE_ENDIAN = 0
 module.exports.MODE_BIG_ENDIAN = 1073741824
 module.exports.MODE_ARM = 1
@@ -33,7 +31,6 @@ module.exports.MODE_SPARC64 = 8
 module.exports.MODE_V9 = 16
 module.exports.ERR_ASM = 128
 module.exports.ERR_ASM_ARCH = 512
-
 module.exports.ERR_OK = 0
 module.exports.ERR_NOMEM = 1
 module.exports.ERR_ARCH = 2
diff --git a/bindings/python/keystone/keystone_const.py b/bindings/python/keystone/keystone_const.py
index 8836f8f9b00bd52cf626f398830f54657549c065..17c70680988b7400ae43747623301b21feabda44 100644
--- a/bindings/python/keystone/keystone_const.py
+++ b/bindings/python/keystone/keystone_const.py
@@ -1,6 +1,5 @@
 # For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [keystone_const.py]
 KS_API_MAJOR = 1
-
 KS_API_MINOR = 0
 KS_ARCH_ARM = 1
 KS_ARCH_ARM64 = 2
@@ -11,7 +10,6 @@ KS_ARCH_SPARC = 6
 KS_ARCH_SYSTEMZ = 7
 KS_ARCH_HEXAGON = 8
 KS_ARCH_MAX = 9
-
 KS_MODE_LITTLE_ENDIAN = 0
 KS_MODE_BIG_ENDIAN = 1073741824
 KS_MODE_ARM = 1
@@ -33,7 +31,6 @@ KS_MODE_SPARC64 = 8
 KS_MODE_V9 = 16
 KS_ERR_ASM = 128
 KS_ERR_ASM_ARCH = 512
-
 KS_ERR_OK = 0
 KS_ERR_NOMEM = 1
 KS_ERR_ARCH = 2
diff --git a/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb b/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb
index 3c8c23c4554a9c7a81d40a2e474e6a621aaa5cd2..470664544cfde4110c36fb45ca82875d2628fd37 100644
--- a/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb
+++ b/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb
@@ -2,7 +2,6 @@
 
 module Keystone
 	KS_API_MAJOR = 1
-
 	KS_API_MINOR = 0
 	KS_ARCH_ARM = 1
 	KS_ARCH_ARM64 = 2
@@ -13,7 +12,6 @@ module Keystone
 	KS_ARCH_SYSTEMZ = 7
 	KS_ARCH_HEXAGON = 8
 	KS_ARCH_MAX = 9
-
 	KS_MODE_LITTLE_ENDIAN = 0
 	KS_MODE_BIG_ENDIAN = 1073741824
 	KS_MODE_ARM = 1
@@ -35,7 +33,6 @@ module Keystone
 	KS_MODE_V9 = 16
 	KS_ERR_ASM = 128
 	KS_ERR_ASM_ARCH = 512
-
 	KS_ERR_OK = 0
 	KS_ERR_NOMEM = 1
 	KS_ERR_ARCH = 2
diff --git a/bindings/rust/.gitignore b/bindings/rust/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..ce906b8f897bcd1482cbfbd2b1205dfb4678ab8c
--- /dev/null
+++ b/bindings/rust/.gitignore
@@ -0,0 +1,3 @@
+Cargo.lock
+target/
+*.bk
diff --git a/bindings/rust/COPYING b/bindings/rust/COPYING
new file mode 100644
index 0000000000000000000000000000000000000000..00ccfbb62888382f5a4ce201a9d5e4bf85bbc373
--- /dev/null
+++ b/bindings/rust/COPYING
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/bindings/rust/Cargo.toml b/bindings/rust/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..93c9f384b36c7be0f1e58ebab3846dbad2da4d52
--- /dev/null
+++ b/bindings/rust/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "keystone"
+version = "0.1.0"
+authors = ["Remco Verhoef <remco.verhoef@dutchcoders.io>"]
+description = "Rust bindings for the keystone-engine"
+license = "GPL-2.0"
+readme = "README.md"
+include = ["src/*", "tests/*", "Cargo.toml", "COPYING", "README.md"]
+
+[dependencies]
+libc = "0.2.*"
+bitflags = "0.7.0"
diff --git a/bindings/rust/Makefile b/bindings/rust/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..b360c22a5628b694c3fd75dd2af675024dda8c8c
--- /dev/null
+++ b/bindings/rust/Makefile
@@ -0,0 +1,22 @@
+# Python binding for Keystone engine. Nguyen Anh Quynh <aquynh@gmail.com>
+
+ifndef BUILDDIR
+OBJDIR = ./build
+else
+OBJDIR = $(abspath $(BUILDDIR))/obj/bindings/rust
+endif
+
+.PHONY: gen_const install install3 clean
+
+gen_const:
+	cd .. && python const_generator.py rust
+
+install:
+	cargo build
+
+clean:
+	rm -rf target/
+
+check:
+	cargo test
+
diff --git a/bindings/rust/README.md b/bindings/rust/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a8ef3eba1fb8edaba4c1c0e085362dc7c089f18d
--- /dev/null
+++ b/bindings/rust/README.md
@@ -0,0 +1,32 @@
+# keystone-rs
+Rust bindings for the [keystone](http://www.keystone-engine.org/) engine.
+
+```rust
+extern crate keystone;
+use keystone::{Keystone, Arch, Mode, OptionType, OptionValue};
+
+fn main() {
+    let engine = Keystone::new(Arch::X86, Mode::Mode32)
+        .expect("Could not initialize Keystone engine");
+
+    engine.option(OptionType::Syntax, OptionValue::SyntaxNASM)
+        .expect("Could not set option to nasm syntax");
+
+    let result = engine.asm("mov ah, 0x80".to_string(), 0)
+        .expect("Could not assemble");
+
+    let _ = result;
+}
+```
+
+## Installation
+
+## Notes
+
+## Contributing
+
+Contributors:
+- Remco Verhoef (@remco_verhoef)
+
+Special thanks to:
+- Sébastien Duquette (@ekse) for his [unicorn-rs](https://github.com/ekse/unicorn-rs) binding
diff --git a/bindings/rust/examples/asm.rs b/bindings/rust/examples/asm.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4676a645f9ae5e9c286c73f39ca750f4fa48ad03
--- /dev/null
+++ b/bindings/rust/examples/asm.rs
@@ -0,0 +1,20 @@
+extern crate keystone;
+use keystone::*;
+
+fn main() {
+    let engine = Keystone::new(Arch::X86, MODE_32)
+        .expect("Could not initialize Keystone engine");
+
+    engine.option(OptionType::SYNTAX, OPT_SYNTAX_NASM)
+        .expect("Could not set option to nasm syntax");
+
+    let result = engine.asm("mov ah, 0x80".to_string(), 0)
+        .expect("Could not assemble");
+
+    println!("ASM result: {}", result);
+
+    if let Err(err) = engine.asm("INVALID".to_string(), 0) {
+        println!("Error: {}", err);
+    }
+}
+
diff --git a/bindings/rust/src/enums.rs b/bindings/rust/src/enums.rs
new file mode 100644
index 0000000000000000000000000000000000000000..45516be71266e26d601742ec671ee6d93763b056
--- /dev/null
+++ b/bindings/rust/src/enums.rs
@@ -0,0 +1,101 @@
+pub use keystone_const::*;
+
+#[repr(u32)]
+#[derive(Debug, PartialEq, Clone, Copy)]
+pub enum Arch {
+    ARM = KS_ARCH_ARM,
+    ARM64 =KS_ARCH_ARM64,
+    MIPS = KS_ARCH_MIPS,
+    X86 = KS_ARCH_X86,
+    PPC = KS_ARCH_PPC,
+    SPARC = KS_ARCH_SPARC,
+    SYSTEMZ = KS_ARCH_SYSTEMZ,
+    HEXAGON = KS_ARCH_HEXAGON,
+}
+
+#[repr(u32)]
+#[derive(Debug, PartialEq, Clone, Copy)]
+pub enum Mode {
+    LittleEndian = KS_MODE_LITTLE_ENDIAN,
+    BigEndian = KS_MODE_BIG_ENDIAN,
+    /*
+    ARM = KS_MODE_ARM,
+    THUMB = KS_MODE_THUMB,
+    V8 = KS_MODE_V8,
+    MICRO = KS_MODE_MICRO,
+    MIPS3 = KS_MODE_MIPS3,
+    MIPS32R6 = KS_MODE_MIPS32R6,
+    MIPS32 = KS_MODE_MIPS32,
+    MIPS64 = KS_MODE_MIPS64,
+    SIZE_16= KS_MODE_16,
+    */
+    Mode32 = KS_MODE_32,
+    /*
+    SIZE_64 = KS_MODE_64,
+    PPC32 = KS_MODE_PPC32,
+    PPC64 = KS_MODE_PPC64,
+    QPX = KS_MODE_QPX,
+    SPARC32 = KS_MODE_SPARC32,
+    SPARC64 = KS_MODE_SPARC64,
+    V9 = KS_MODE_V9,
+    */
+}
+
+#[repr(u32)]
+#[derive(Debug, PartialEq, Clone, Copy)]
+pub enum Error {
+    Ok = KS_ERR_OK,
+    // ASM = KS_ERR_ASM,
+    // ASM_ARCH = KS_ERR_ASM_ARCH,
+    NoMem = KS_ERR_NOMEM,
+    Arch = KS_ERR_ARCH,
+    Handle = KS_ERR_HANDLE,
+    Mode = KS_ERR_MODE,
+    Version = KS_ERR_VERSION,
+    OptionInvalid = KS_ERR_OPT_INVALID,
+    AsmExprToken = KS_ERR_ASM_EXPR_TOKEN,
+    AsmDirectiveValueRange = KS_ERR_ASM_DIRECTIVE_VALUE_RANGE,
+    AsmDirectiveToken = KS_ERR_ASM_DIRECTIVE_ID,
+    DirectiveToken = KS_ERR_ASM_DIRECTIVE_TOKEN,
+    DirectiveStr =  KS_ERR_ASM_DIRECTIVE_STR,
+    DirectiveComma =  KS_ERR_ASM_DIRECTIVE_COMMA,
+    DirectiveRelocName =  KS_ERR_ASM_DIRECTIVE_RELOC_NAME,
+    DirectiveRelocToken =  KS_ERR_ASM_DIRECTIVE_RELOC_TOKEN,
+    DirectiveFPoint =  KS_ERR_ASM_DIRECTIVE_FPOINT,
+    VariantInvalid =  KS_ERR_ASM_VARIANT_INVALID,
+    ExprBracket =  KS_ERR_ASM_EXPR_BRACKET,
+    SymbolModifier =  KS_ERR_ASM_SYMBOL_MODIFIER,
+    RParen =  KS_ERR_ASM_RPAREN,
+    StatToken =  KS_ERR_ASM_STAT_TOKEN,
+    AsmUnsupported = KS_ERR_ASM_UNSUPPORTED,
+    AsmMacroToken = KS_ERR_ASM_MACRO_TOKEN,
+    AsmMacroParen = KS_ERR_ASM_MACRO_PAREN,
+    AsmMacroEQU = KS_ERR_ASM_MACRO_EQU,
+    AsmMacroArgs = KS_ERR_ASM_MACRO_ARGS,
+    AsmMacroLevelsExceed = KS_ERR_ASM_MACRO_LEVELS_EXCEED,
+    AsmEscBackslash = KS_ERR_ASM_ESC_BACKSLASH,
+    AsmEscOctal = KS_ERR_ASM_ESC_OCTAL,
+    AsmEscSequence =  KS_ERR_ASM_ESC_SEQUENCE,
+    AsmInvalidOperand = KS_ERR_ASM_INVALIDOPERAND,
+    AsmMissingFeature = KS_ERR_ASM_MISSINGFEATURE,
+    AsmMNemonicFail = KS_ERR_ASM_MNEMONICFAIL,
+}
+
+#[repr(u32)]
+#[derive(Debug, PartialEq, Clone, Copy)]
+pub enum OptionType {
+    Syntax = KS_OPT_SYNTAX,
+    SYNTAX2 = KS_OPT_SYNTAX_NASM,
+}
+
+#[repr(u32)]
+#[derive(Debug, PartialEq, Clone, Copy)]
+pub enum OptionValue {
+    SyntaxIntel = KS_OPT_SYNTAX_INTEL,
+    SyntaxATT = KS_OPT_SYNTAX_ATT,
+    SyntaxNASM = KS_OPT_SYNTAX_NASM,
+    SyntaxMASM = KS_OPT_SYNTAX_MASM,
+    SyntaxGAS = KS_OPT_SYNTAX_GAS,
+}
+
+
diff --git a/bindings/rust/src/ffi.rs b/bindings/rust/src/ffi.rs
new file mode 100644
index 0000000000000000000000000000000000000000..1fd2389557fe0d725e551ff857dbbe08a382c39d
--- /dev/null
+++ b/bindings/rust/src/ffi.rs
@@ -0,0 +1,28 @@
+//! Keystone Assembler Engine (www.keystone-engine.org) */
+//! By Nguyen Anh Quynh <aquynh@gmail.com>, 2016 */
+//! Rust bindings by Remco Verhoef <remco@dutchcoders.io>, 2016 */
+//!
+
+use libc;
+use std::os::raw::c_char;
+
+use ks_handle;
+
+#[link(name = "keystone")]
+extern "C" {
+    pub fn ks_version(major: *const u32, minor: *const u32) -> u32;
+    pub fn ks_arch_supported(arch: u32) -> bool;
+    pub fn ks_open(arch: u32, mode: u32, engine: *mut ks_handle) -> u32;
+    pub fn ks_asm(engine: ks_handle,
+                  string: *const c_char,
+                  address: u64,
+                  encoding: *mut *mut libc::c_uchar,
+                  encoding_size: *mut libc::size_t,
+                  stat_count: *mut libc::size_t)
+                  -> u32;
+    pub fn ks_errno(engine: ks_handle) -> u32;
+    pub fn ks_strerror(error_code: u32) -> *const c_char;
+    pub fn ks_option(engine: ks_handle, type_: u32, value: libc::size_t) -> u32;
+    pub fn ks_close(engine: ks_handle);
+    pub fn ks_free(encoding: *mut libc::c_uchar);
+}
diff --git a/bindings/rust/src/keystone_const.rs b/bindings/rust/src/keystone_const.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ed0b0e8496f42258c57bba20ec4f5adf98642c63
--- /dev/null
+++ b/bindings/rust/src/keystone_const.rs
@@ -0,0 +1,146 @@
+// For Keystone Engine. AUTO-GENERATED FILE, DO NOT EDIT [keystone_const.rs]
+extern crate libc;
+
+
+pub const KS_API_MAJOR: u32 = 1;
+pub const KS_API_MINOR: u32 = 0;
+pub const KS_ARCH_ARM: u32 = 1;
+pub const KS_ARCH_ARM64: u32 = 2;
+pub const KS_ARCH_MIPS: u32 = 3;
+pub const KS_ARCH_X86: u32 = 4;
+pub const KS_ARCH_PPC: u32 = 5;
+pub const KS_ARCH_SPARC: u32 = 6;
+pub const KS_ARCH_SYSTEMZ: u32 = 7;
+pub const KS_ARCH_HEXAGON: u32 = 8;
+pub const KS_ARCH_MAX: u32 = 9;
+
+
+bitflags! {
+	pub flags Mode : u32 {
+		const MODE_LITTLE_ENDIAN = 0,
+		const MODE_BIG_ENDIAN = 1073741824,
+		const MODE_ARM = 1,
+		const MODE_THUMB = 16,
+		const MODE_V8 = 64,
+		const MODE_MICRO = 16,
+		const MODE_MIPS3 = 32,
+		const MODE_MIPS32R6 = 64,
+		const MODE_MIPS32 = 4,
+		const MODE_MIPS64 = 8,
+		const MODE_16 = 2,
+		const MODE_32 = 4,
+		const MODE_64 = 8,
+		const MODE_PPC32 = 4,
+		const MODE_PPC64 = 8,
+		const MODE_QPX = 16,
+		const MODE_SPARC32 = 4,
+		const MODE_SPARC64 = 8,
+		const MODE_V9 = 16,
+	}
+}
+
+#[derive(Debug, PartialEq, Clone, Copy)]
+pub enum Arch {
+    ARM,
+    ARM64,
+    MIPS,
+    X86,
+    PPC,
+    SPARC,
+    SYSTEMZ,
+    HEXAGON,
+    MAX,
+}
+
+
+impl Arch {
+    #[inline]
+    pub fn val(&self) -> u32 {
+        match *self {
+            Arch::ARM => 1,
+            Arch::ARM64 => 2,
+            Arch::MIPS => 3,
+            Arch::X86 => 4,
+            Arch::PPC => 5,
+            Arch::SPARC => 6,
+            Arch::SYSTEMZ => 7,
+            Arch::HEXAGON => 8,
+            Arch::MAX => 9,
+        }
+    }
+}
+
+#[derive(Debug, PartialEq, Clone, Copy)]
+pub enum OptionType {
+    SYNTAX,
+    MAX,
+}
+
+impl OptionType {
+    #[inline]
+    pub fn val(&self) -> u32 {
+        match *self {
+            OptionType::SYNTAX => 1,
+            OptionType::MAX => 99,
+        }
+    }
+}
+
+bitflags! {
+	pub flags OptionValue : libc::size_t {
+		const OPT_SYNTAX_INTEL = 1,
+		const OPT_SYNTAX_ATT = 2,
+		const OPT_SYNTAX_NASM = 4,
+		const OPT_SYNTAX_MASM = 8,
+		const OPT_SYNTAX_GAS = 16,
+	}
+}
+
+bitflags! {
+	pub flags Error : u32 {
+		const ERR_ASM = 128,
+		const ERR_ASM_ARCH = 512,
+		const ERR_OK = 0,
+		const ERR_NOMEM = 1,
+		const ERR_ARCH = 2,
+		const ERR_HANDLE = 3,
+		const ERR_MODE = 4,
+		const ERR_VERSION = 5,
+		const ERR_OPT_INVALID = 6,
+		const ERR_ASM_EXPR_TOKEN = 128,
+		const ERR_ASM_DIRECTIVE_VALUE_RANGE = 129,
+		const ERR_ASM_DIRECTIVE_ID = 130,
+		const ERR_ASM_DIRECTIVE_TOKEN = 131,
+		const ERR_ASM_DIRECTIVE_STR = 132,
+		const ERR_ASM_DIRECTIVE_COMMA = 133,
+		const ERR_ASM_DIRECTIVE_RELOC_NAME = 134,
+		const ERR_ASM_DIRECTIVE_RELOC_TOKEN = 135,
+		const ERR_ASM_DIRECTIVE_FPOINT = 136,
+		const ERR_ASM_DIRECTIVE_UNKNOWN = 137,
+		const ERR_ASM_VARIANT_INVALID = 138,
+		const ERR_ASM_DIRECTIVE_EQU = 139,
+		const ERR_ASM_EXPR_BRACKET = 140,
+		const ERR_ASM_SYMBOL_MODIFIER = 141,
+		const ERR_ASM_SYMBOL_REDEFINED = 142,
+		const ERR_ASM_SYMBOL_MISSING = 143,
+		const ERR_ASM_RPAREN = 144,
+		const ERR_ASM_STAT_TOKEN = 145,
+		const ERR_ASM_UNSUPPORTED = 146,
+		const ERR_ASM_MACRO_TOKEN = 147,
+		const ERR_ASM_MACRO_PAREN = 148,
+		const ERR_ASM_MACRO_EQU = 149,
+		const ERR_ASM_MACRO_ARGS = 150,
+		const ERR_ASM_MACRO_LEVELS_EXCEED = 151,
+		const ERR_ASM_MACRO_STR = 152,
+		const ERR_ASM_ESC_BACKSLASH = 153,
+		const ERR_ASM_ESC_OCTAL = 154,
+		const ERR_ASM_ESC_SEQUENCE = 155,
+		const ERR_ASM_ESC_STR = 156,
+		const ERR_ASM_TOKEN_INVALID = 157,
+		const ERR_ASM_INSN_UNSUPPORTED = 158,
+		const ERR_ASM_FIXUP_INVALID = 159,
+		const ERR_ASM_INVALIDOPERAND = 512,
+		const ERR_ASM_MISSINGFEATURE = 513,
+		const ERR_ASM_MNEMONICFAIL = 514,
+	}
+}
diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..dac0912be91fd0b6360710af4222e70222a93289
--- /dev/null
+++ b/bindings/rust/src/lib.rs
@@ -0,0 +1,189 @@
+//! Keystone Assembler Engine (www.keystone-engine.org) */
+//! By Nguyen Anh Quynh <aquynh@gmail.com>, 2016 */
+//! Rust bindings by Remco Verhoef <remco@dutchcoders.io>, 2016 */
+//!
+//! ```rust
+//! extern crate keystone;
+//! use keystone::{Keystone, Arch, OptionType};
+//!
+//! fn main() {
+//!     let engine = Keystone::new(Arch::X86, keystone::MODE_32)
+//!         .expect("Could not initialize Keystone engine");
+//!     engine.option(OptionType::SYNTAX, keystone::OPT_SYNTAX_NASM)
+//!         .expect("Could not set option to nasm syntax");
+//!     let result = engine.asm("mov ah, 0x80".to_string(), 0)
+//!         .expect("Could not assemble");
+//! }
+//! ```
+
+#![doc(html_root_url="https://keystone/doc/here/v1")]
+
+#[macro_use]
+extern crate bitflags;
+extern crate libc;
+
+pub mod ffi;
+// pub mod enums;
+pub mod keystone_const;
+// pub mod arm64_const;
+// pub mod arm_const;
+// pub mod hexagon_const;
+// pub mod mips_const;
+// pub mod ppc_const;
+// pub mod sparc_const;
+// pub mod systemz_const;
+// pub mod x86_const;
+
+use std::ffi::CStr;
+use std::ffi::CString;
+use std::fmt;
+
+pub use keystone_const::*;
+
+#[allow(non_camel_case_types)]
+pub type ks_handle = libc::size_t;
+
+impl Error {
+    pub fn msg(&self) -> String {
+        error_msg(*self)
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.msg())
+    }
+}
+
+#[derive(Debug, PartialEq)]
+pub struct AsmResult {
+    pub size: u32,
+    pub stat_count: u32,
+    pub bytes: Vec<u8>,
+}
+
+impl fmt::Display for AsmResult {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        for byte in &self.bytes {
+            try!(f.write_fmt(format_args!("{:02x}", byte)));
+        }
+
+        Ok(())
+    }
+}
+
+pub fn bindings_version() -> (u32, u32) {
+    (KS_API_MAJOR, KS_API_MINOR)
+}
+
+/// Return tuple `(major, minor)` API version numbers.
+pub fn version() -> (u32, u32) {
+    let mut major: u32 = 0;
+    let mut minor: u32 = 0;
+
+    unsafe {
+        ffi::ks_version(&mut major, &mut minor);
+    }
+    (major, minor)
+}
+
+/// Return tuple `(major, minor)` API version numbers.
+pub fn arch_supported(arch: Arch) -> bool {
+    unsafe { ffi::ks_arch_supported(arch.val()) }
+}
+
+/// Return a string describing given error code.
+pub fn error_msg(error: Error) -> String {
+    unsafe { CStr::from_ptr(ffi::ks_strerror(error.bits())).to_string_lossy().into_owned() }
+}
+
+pub struct Keystone {
+    handle: ks_handle,
+}
+
+impl Keystone {
+    /// Create new instance of Keystone engine.
+    pub fn new(arch: Arch, mode: Mode) -> Result<Keystone, Error> {
+        if version() != bindings_version() {
+            return Err(ERR_VERSION);
+        }
+
+        let mut handle: ks_handle = 0;
+
+        let err = Error::from_bits_truncate(unsafe {
+            ffi::ks_open(arch.val(), mode.bits(), &mut handle)
+        });
+        if err == ERR_OK {
+            Ok(Keystone { handle: handle })
+        } else {
+            Err(err)
+        }
+    }
+
+    /// Report the last error number when some API function fail.
+    pub fn error(&self) -> Result<(), Error> {
+        let err = Error::from_bits_truncate(unsafe { ffi::ks_errno(self.handle) });
+        if err == ERR_OK {
+            Ok(())
+        } else {
+            Err(err)
+        }
+    }
+
+    /// Set option for Keystone engine at runtime
+    pub fn option(&self, type_: OptionType, value: OptionValue) -> Result<(), Error> {
+        let err = Error::from_bits_truncate(unsafe {
+            ffi::ks_option(self.handle, type_.val(), value.bits())
+        });
+        if err == ERR_OK {
+            Ok(())
+        } else {
+            Err(err)
+        }
+    }
+
+    /// Assemble a string given its the buffer, size, start address and number
+    /// of instructions to be decoded.
+    ///
+    /// This API dynamically allocate memory to contain assembled instruction.
+    /// Resulted array of bytes containing the machine code  is put into @*encoding
+    pub fn asm(&self, str: String, address: u64) -> Result<AsmResult, Error> {
+        let mut size: libc::size_t = 0;
+        let mut stat_count: libc::size_t = 0;
+
+        let s = CString::new(str).unwrap();
+        let mut ptr: *mut libc::c_uchar = std::ptr::null_mut();
+
+        let err = Error::from_bits_truncate(unsafe {
+            ffi::ks_asm(self.handle,
+                        s.as_ptr(),
+                        address,
+                        &mut ptr,
+                        &mut size,
+                        &mut stat_count)
+        });
+
+        if err == ERR_OK {
+            let bytes = unsafe { std::slice::from_raw_parts(ptr, size) };
+
+            unsafe {
+                ffi::ks_free(ptr);
+            };
+
+            Ok(AsmResult {
+                size: size as u32,
+                stat_count: stat_count as u32,
+                bytes: From::from(&bytes[..]),
+            })
+        } else {
+            let err = Error::from_bits_truncate(unsafe { ffi::ks_errno(self.handle) });
+            Err(err)
+        }
+    }
+}
+
+impl Drop for Keystone {
+    fn drop(&mut self) {
+        unsafe { ffi::ks_close(self.handle) };
+    }
+}
diff --git a/bindings/rust/tests/keystone.rs b/bindings/rust/tests/keystone.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ed96ecec2f6f06187a08a5b6bba4a366284be9b1
--- /dev/null
+++ b/bindings/rust/tests/keystone.rs
@@ -0,0 +1,48 @@
+extern crate keystone;
+
+use keystone::{Keystone, Arch, OptionType};
+
+#[test]
+fn version() {
+    let (major, minor) = keystone::version();
+    assert_eq!((major, minor), keystone::bindings_version());
+}
+
+#[test]
+fn arch_supported() {
+    assert_eq!(keystone::arch_supported(Arch::ARM), true);
+    assert_eq!(keystone::arch_supported(Arch::X86), true);
+}
+
+#[test]
+fn asm() {
+    let asm = String::from("mov ah, 0x80\n nop\n mov al, 0x81\n");
+
+    let engine = Keystone::new(Arch::X86, keystone::MODE_LITTLE_ENDIAN | keystone::MODE_32)
+        .expect("Could not initialize Keystone engine");
+
+    engine.option(OptionType::SYNTAX, keystone::OPT_SYNTAX_NASM)
+        .expect("Could not set option to nasm syntax");
+
+    let result = engine.asm(asm, 0)
+        .expect("Could not assemble");
+
+    print!("{0:?}", result.bytes);
+    assert_eq!(result.bytes,[0xb4,0x80, 0x90, 0xb0, 0x81]);
+}
+
+#[test]
+fn invalid_asm() {
+    let asm = String::from("invalid asm");
+
+    let engine = Keystone::new(Arch::X86, keystone::MODE_32)
+        .expect("Could not initialize Keystone engine");
+
+    let result = engine.asm(asm, 0);
+    let err = result.unwrap_err();
+
+    assert_eq!(err, keystone::ERR_ASM_MNEMONICFAIL);
+    assert_eq!(err.msg(), "Invalid mnemonic (KS_ERR_ASM_MNEMONICFAIL)");
+    assert_eq!(format!("{}", err), "Invalid mnemonic (KS_ERR_ASM_MNEMONICFAIL)");
+}
+