diff --git a/.DS_Store b/.DS_Store
new file mode 100644
Binary files /dev/null and b/.DS_Store differ
diff --git a/._.DS_Store b/._.DS_Store
new file mode 100644
Binary files /dev/null and b/._.DS_Store differ
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Author name here (c) 2017
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Author name here nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,29 @@
+# NMIS file parser 
+ - NMIS stands for Network Management Information System
+
+This parser parses the NMIS format files to `Nmis` record type
+
+#### Example usage :
+
+```haskell
+  module Main where
+  import System.Environment (getArgs)
+  import System.IO
+  import Text.Megaparsec
+  import Text.Nmis
+
+  main :: IO ()
+  main = do
+    args <- getArgs
+    case args of
+      [] -> putStrLn "error: you need to pass in file path"
+      [path] -> do
+              contents <- readFile path
+              let result = parse parseNmis "" contents
+              case result of
+                  Left nodes -> print $ parseErrorPretty nodes
+                  Right nodes -> do
+                      print nodes
+      _ -> putStrLn "error: you need to pass in only one file path"
+
+```
diff --git a/nmis-parser.cabal b/nmis-parser.cabal
new file mode 100644
--- /dev/null
+++ b/nmis-parser.cabal
@@ -0,0 +1,40 @@
+name:                nmis-parser
+version:             0.1.0.0
+synopsis:            NMIS file parser
+homepage:            https://github.com/v0d1ch/nmis-parser#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Sasa Bogicevic
+maintainer:          brutallesale@gmail.com
+copyright:           2017 Sasa Bogicevic
+category:            Text, Parsers
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+
+description:
+     Parser for __NMIS__ (Network Management Information System) files to record type. Main module to use is __Text.Nmis__ and __parseNmis__ function
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Text.Nmis
+                     , Text.Internal.Helper
+                     , Text.Internal.NmisTypes
+  build-depends:       base >= 4.7 && < 5
+                     , containers
+                     , megaparsec
+  default-language:    Haskell2010
+
+
+test-suite nmis-test
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  main-is:             Spec.hs
+  build-depends:       base
+                     , Nmis
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/v0d1ch/nmis-parser
diff --git a/src/Text/Internal/Helper.hs b/src/Text/Internal/Helper.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Internal/Helper.hs
@@ -0,0 +1,93 @@
+{-|
+Module      : Text.Internal.Helper
+Description : Helper for parse actions 
+Copyright   : (c) Sasa Bogicevic, 2017
+License     : GPL-3
+Maintainer  : brutallesale@gmail.com
+Stability   : experimental
+Uses megaparsec library 
+-}
+
+{-# LANGUAGE OverloadedStrings #-}
+
+module Text.Internal.Helper where
+
+import Control.Applicative (empty)
+import Control.Monad (void)
+import Prelude hiding (until)
+import Text.Megaparsec
+import qualified Text.Megaparsec.Lexer as L
+import Text.Megaparsec.String
+
+-- | space consumer - consume space and comments
+spaceConsumer :: Parser ()
+spaceConsumer = L.space (void spaceChar) lineCmnt blockCmnt
+  where
+    lineCmnt = L.skipLineComment "#"
+    blockCmnt = L.skipBlockComment "/*" "*/"
+-- | hashbang line comment
+lineComment :: Parser ()
+lineComment = L.skipLineComment "#"
+
+-- | space consumer no 2
+scn :: Parser ()
+scn = L.space (void spaceChar) lineComment empty
+
+-- | lexeme
+lexeme :: Parser a -> Parser a
+lexeme = L.lexeme spaceConsumer
+
+-- | symbol
+symbol :: String -> Parser String
+symbol = L.symbol scn
+
+-- | arrow - parse haskell constraint like arrow sign
+parrow :: Parser String
+parrow = lexeme $ string " => "
+
+-- | equals - parse equals sign
+pequals :: Parser String
+pequals = lexeme $ string " = "
+
+-- | parse all between parens
+parens :: Parser a -> Parser a
+parens = between (string "(") (string ")")
+
+-- | parse all between braces
+braces :: Parser a -> Parser a
+braces = between (string "{") (string "}")
+
+-- | parse until string passed as function parameter
+until :: String -> Parsec Dec String String
+until s = anyChar `manyTill` string s
+
+-- | parse until newline character
+untilEol :: Parsec Dec String String
+untilEol = anyChar `someTill` newline
+
+-- | parse until newline character
+phash :: Parser String
+phash = lexeme $ string' "%hash" >> pequals
+
+-- | parse quoted string with optional space in front of it
+pQuotedStr :: Parser String
+pQuotedStr = do
+  _ <- optional space
+  string' "'" >> until "'"
+
+-- | parse 'undef' literal
+pUndefined :: Parser String
+pUndefined = do
+  _ <- optional space
+  string' "undef"
+
+-- | combined parser for single record
+pOpt :: Parser (String, String)
+pOpt = do
+  _ <- space
+  key <- pQuotedStr
+  _ <- space >> string "=>" >> space
+  value <- try (pQuotedStr <|> pUndefined <|> many numberChar)
+  _ <- optional $ string' ","
+  _ <- newline
+  return (key, value)
diff --git a/src/Text/Internal/Helper.hs~ b/src/Text/Internal/Helper.hs~
new file mode 100644
--- /dev/null
+++ b/src/Text/Internal/Helper.hs~
@@ -0,0 +1,84 @@
+{-# LANGUAGE OverloadedStrings #-}
+-- | This helper module contains functions to parse nmis file.
+-- It uses megapasec library
+module Helper where
+
+import Control.Applicative (empty)
+import Control.Monad (void)
+import Prelude hiding (until)
+import Text.Megaparsec
+import qualified Text.Megaparsec.Lexer as L
+import Text.Megaparsec.String
+
+-- | space consumer - consume space and comments
+spaceConsumer :: Parser ()
+spaceConsumer = L.space (void spaceChar) lineCmnt blockCmnt
+  where
+    lineCmnt = L.skipLineComment "#"
+    blockCmnt = L.skipBlockComment "/*" "*/"
+-- | hashbang line comment
+lineComment :: Parser ()
+lineComment = L.skipLineComment "#"
+
+-- | space consumer no 2
+scn :: Parser ()
+scn = L.space (void spaceChar) lineComment empty
+
+-- | lexeme
+lexeme :: Parser a -> Parser a
+lexeme = L.lexeme spaceConsumer
+
+-- | symbol
+symbol :: String -> Parser String
+symbol = L.symbol scn
+
+-- | arrow - parse haskell constraint like arrow sign
+parrow :: Parser String
+parrow = lexeme $ string " => "
+
+-- | equals - parse equals sign
+pequals :: Parser String
+pequals = lexeme $ string " = "
+
+-- | parse all between parens
+parens :: Parser a -> Parser a
+parens = between (string "(") (string ")")
+
+-- | parse all between braces
+braces :: Parser a -> Parser a
+braces = between (string "{") (string "}")
+
+-- | parse until string passed as function parameter
+until :: String -> Parsec Dec String String
+until s = anyChar `manyTill` string s
+
+-- | parse until newline character
+untilEol :: Parsec Dec String String
+untilEol = anyChar `someTill` newline
+
+-- | parse until newline character
+phash :: Parser String
+phash = lexeme $ string' "%hash" >> pequals
+
+-- | parse quoted string with optional space in front of it
+pQuotedStr :: Parser String
+pQuotedStr = do
+  _ <- optional space
+  string' "'" >> until "'"
+
+-- | parse 'undef' literal
+pUndefined :: Parser String
+pUndefined = do
+  _ <- optional space
+  string' "undef"
+
+-- | combined parser for single record
+pOpt :: Parser (String, String)
+pOpt = do
+  _ <- space
+  key <- pQuotedStr
+  _ <- space >> string "=>" >> space
+  value <- try (pQuotedStr <|> pUndefined <|> many numberChar)
+  _ <- optional $ string' ","
+  _ <- newline
+  return (key, value)
diff --git a/src/Text/Internal/NmisTypes.hs b/src/Text/Internal/NmisTypes.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Internal/NmisTypes.hs
@@ -0,0 +1,44 @@
+{-|
+Module      : Text.Internal.NmisTypes
+Description : Contains single type that holds all parsed data  
+Copyright   : (c) Sasa Bogicevic, 2017
+License     : GPL-3
+Maintainer  : brutallesale@gmail.com
+Stability   : experimental
+-}
+module Text.Internal.NmisTypes where
+
+-- | Main type that holds all parsed data
+data Nmis = Nmis
+  { customer :: Maybe String
+  , groups :: Maybe String
+  , active :: Maybe String
+  , advancedOptions :: Maybe String
+  , authKey :: Maybe String
+  , authPassword :: Maybe String
+  , authProtocol :: Maybe String
+  , businessService :: Maybe String
+  , calls :: Maybe String
+  , cbqos :: Maybe String
+  , collect :: Maybe String
+  , community :: Maybe String
+  , depend :: Maybe String
+  , display_name :: Maybe String
+  , group :: Maybe String
+  , host :: Maybe String
+  , location :: Maybe String
+  , model :: Maybe String
+  , name :: Maybe String
+  , netType :: Maybe String
+  , ping :: Maybe String
+  , port :: Maybe String
+  , rancid :: Maybe String
+  , roleType :: Maybe String
+  , serviceStatus :: Maybe String
+  , services :: Maybe String
+  , threshold :: Maybe String
+  , timezone :: Maybe Integer
+  , uuid :: Maybe String
+  , version :: Maybe String
+  , webserver :: Maybe String
+  } deriving (Show)
diff --git a/src/Text/Internal/NmisTypes.hs~ b/src/Text/Internal/NmisTypes.hs~
new file mode 100644
--- /dev/null
+++ b/src/Text/Internal/NmisTypes.hs~
@@ -0,0 +1,36 @@
+module NmisTypes where
+
+-- | Main type that containes all parsed data
+data Nmis = Nmis
+  { customer :: Maybe String
+  , groups :: Maybe String
+  , active :: Maybe String
+  , advancedOptions :: Maybe String
+  , authKey :: Maybe String
+  , authPassword :: Maybe String
+  , authProtocol :: Maybe String
+  , businessService :: Maybe String
+  , calls :: Maybe String
+  , cbqos :: Maybe String
+  , collect :: Maybe String
+  , community :: Maybe String
+  , depend :: Maybe String
+  , display_name :: Maybe String
+  , group :: Maybe String
+  , host :: Maybe String
+  , location :: Maybe String
+  , model :: Maybe String
+  , name :: Maybe String
+  , netType :: Maybe String
+  , ping :: Maybe String
+  , port :: Maybe String
+  , rancid :: Maybe String
+  , roleType :: Maybe String
+  , serviceStatus :: Maybe String
+  , services :: Maybe String
+  , threshold :: Maybe String
+  , timezone :: Maybe Integer
+  , uuid :: Maybe String
+  , version :: Maybe String
+  , webserver :: Maybe String
+  } deriving (Show)
diff --git a/src/Text/Nmis.hs b/src/Text/Nmis.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Nmis.hs
@@ -0,0 +1,200 @@
+{-|
+Module      : Text.Nmis
+Description : Main module for nmis parsing
+Copyright   : (c) Sasa Bogicevic, 2017
+License     : GPL-3
+Maintainer  : brutallesale@gmail.com
+Stability   : experimental
+
+-}
+
+--   NMIS stands for Network Management Information System
+--
+--   This parser parses the nmis format files to Nmis record type
+--
+--  Example usage :
+--
+--  module Main where
+--
+--  import System.Environment (getArgs)
+--
+--  import System.IO
+--
+--  import Text.Megaparsec
+--
+--  import Text.Nmis
+--
+--  main :: IO ()
+--
+--  main = do
+--
+--    args <- getArgs
+--
+--    case args of
+--
+--      [] -> putStrLn "error: you need to pass in file path"
+--
+--      [path] -> do
+--
+--              contents <- readFile path
+--
+--              let result = parse parseNmis "" contents
+--
+--              case result of
+--
+--                  Left nodes -> print $ parseErrorPretty nodes
+--
+--                  Right nodes -> do
+--
+--                      print nodes
+--
+--      _ -> putStrLn "error: you need to pass in only one file path"
+--
+
+{-# LANGUAGE OverloadedStrings #-}
+
+module Text.Nmis where
+
+
+import Control.Monad (join)
+import qualified Data.Map.Strict as M
+import Prelude hiding (until)
+import Text.Megaparsec
+import Text.Megaparsec.String
+import Text.Read (readMaybe)
+import Data.Maybe (fromMaybe)
+import Text.Internal.NmisTypes
+import Text.Internal.Helper as H
+
+-- |  Parse nmis file to [Nmis]
+--
+--    __This is a single function you will need to parse the file__
+parseNmis :: Parser [Nmis]
+parseNmis =
+  lexeme $ do
+    _ <- optional $ symbol "#"
+    _ <- phash
+    _ <- space >> string "("
+    parseToList
+
+
+-- | Parses single record
+parseSingle :: Parser Nmis
+parseSingle = do
+  _ <- optional H.pQuotedStr
+  _ <- until "=>" >> space >> string "{" >> newline
+  node <- manyTill pOpt (try $ lookAhead $ optional space *> string "}")
+  _ <- optional space >> string "}"
+  _ <- optional $ string ","
+  let rmap = M.fromList node
+  return
+    Nmis
+    { customer = M.lookup "customer" rmap
+    , groups = M.lookup "groups" rmap
+    , active = M.lookup "active" rmap
+    , businessService = M.lookup "businessService" rmap
+    , advancedOptions = M.lookup "advancedOptions" rmap
+    , authKey = M.lookup "authKey" rmap
+    , authPassword = M.lookup "authPassword" rmap
+    , authProtocol = M.lookup "authProtocol" rmap
+    , calls = M.lookup "calls" rmap
+    , cbqos = M.lookup "cbqos" rmap
+    , collect = M.lookup "collect" rmap
+    , community = M.lookup "community" rmap
+    , depend = M.lookup "depend" rmap
+    , display_name = M.lookup "display_name" rmap
+    , group = M.lookup "group" rmap
+    , host = M.lookup "host" rmap
+    , location = M.lookup "location" rmap
+    , model = M.lookup "model" rmap
+    , name = M.lookup "name" rmap
+    , netType = M.lookup "netType" rmap
+    , ping = M.lookup "ping" rmap
+    , port = M.lookup "port" rmap
+    , rancid = M.lookup "rancid" rmap
+    , roleType = M.lookup "roleType" rmap
+    , serviceStatus = M.lookup "serviceStatus" rmap
+    , services = M.lookup "services" rmap
+    , threshold = M.lookup "threshold" rmap
+    , timezone = join $ readMaybe <$> M.lookup "timezone" rmap
+    , uuid = M.lookup "uuid" rmap
+    , version = M.lookup "version" rmap
+    , webserver = M.lookup "webserver" rmap
+    }
+
+
+-- |
+-- This function is used to match records by group/groups field.
+--
+-- You have two lists with Nmis types [Nmis] [Nmis]
+--
+-- and you want to match group field from one to the groups field from the other,
+--
+-- grab a customer field from first list and attach it to the second list which you can save later.
+--
+-- This is something of practical use which I needed in the real world.
+lookupInList :: [Nmis] ->  Nmis -> Nmis
+lookupInList cust n = do
+   let fcusts =  filterByGroup (group n) cust
+   if length fcusts > 0 then
+       n { customer = customer (head fcusts) }
+   else n
+
+-- | Filters Nmis by Nodes group
+filterByGroup :: Maybe String -> [Nmis]  -> [Nmis]
+filterByGroup s cl = filter (\c -> groups c == s) cl
+
+-- | parses many single values until ');'
+parseToList :: Parser [Nmis]
+parseToList = do
+  result <-
+    manyTill parseSingle (try $ lookAhead $ optional space >> string ")")
+  _ <- optional newline
+  _ <- string ")"
+  _ <- optional $ string ";"
+  return result
+
+-- | Show maybe integer for timezone field
+showMaybeInt :: Maybe Integer -> String
+showMaybeInt i = case i of
+  Nothing -> ""
+  Just x -> show x
+
+-- | Show Nmis list
+--
+-- Use for printing the [Nmis] list
+showNmis :: [Nmis] -> String
+showNmis [] =  ""
+showNmis (c:cx) =
+  "\n  '" ++ fromMaybe "" (name c) ++ "' => {\n"
+  ++ "    'customer' => '" ++ fromMaybe ""  (customer c) ++ "',\n"
+  ++ "    'active' => '" ++ fromMaybe ""  (active c) ++ "',\n"
+  ++ "    'authkey' => '" ++ fromMaybe ""  (authKey c) ++ "',\n"
+  ++ "    'authpassword' => '" ++ fromMaybe ""  (authPassword c) ++ "',\n"
+  ++ "    'authprotocol' => '" ++ fromMaybe ""  (authProtocol c) ++ "',\n"
+  ++ "    'businesService' => '" ++ fromMaybe "" (businessService c) ++ "',\n"
+  ++ "    'calls' => '" ++ fromMaybe ""  (calls c) ++ "',\n"
+  ++ "    'cbqos' => '" ++ fromMaybe ""  (cbqos c) ++ "',\n"
+  ++ "    'collect' => '" ++ fromMaybe ""  (collect c) ++ "',\n"
+  ++ "    'community' => '" ++ fromMaybe ""  (community c) ++ "',\n"
+  ++ "    'depend' => '" ++ fromMaybe ""  (depend c) ++ "',\n"
+  ++ "    'display_name' => '" ++ fromMaybe "" (display_name c) ++ "',\n"
+  ++ "    'group' => '" ++ fromMaybe ""  (group c) ++ "',\n"
+  ++ "    'host' => '" ++ fromMaybe ""  (host c) ++ "',\n"
+  ++ "    'location' => '" ++ fromMaybe ""  (location c) ++ "',\n"
+  ++ "    'model' => '" ++ fromMaybe ""  (model c) ++ "',\n"
+  ++ "    'name' => '" ++ fromMaybe ""  (name c) ++ "',\n"
+  ++ "    'netType' => '" ++ fromMaybe ""  (netType c) ++ "',\n"
+  ++ "    'ping' => '" ++ fromMaybe ""  (ping c) ++ "',\n"
+  ++ "    'port' => '" ++ fromMaybe ""  (port c) ++ "',\n"
+  ++ "    'rancid' => '" ++ fromMaybe ""  (rancid c) ++ "',\n"
+  ++ "    'roleType' => '" ++ fromMaybe ""  (roleType c) ++ "',\n"
+  ++ "    'serviceStatus' => '" ++ fromMaybe ""  (serviceStatus c) ++ "',\n"
+  ++ "    'services' => '" ++ fromMaybe ""  (services c) ++ "',\n"
+  ++ "    'threshold' => '" ++ fromMaybe ""  (threshold c) ++ "',\n"
+  ++ "    'timezone' => '" ++ showMaybeInt (timezone c) ++ "',\n"
+  ++ "    'uuid' => '" ++ fromMaybe ""  (uuid c) ++ "',\n"
+  ++ "    'version' => '" ++ fromMaybe ""  (version c) ++ "',\n"
+  ++ "    'webserver' => '" ++ fromMaybe ""  (webserver c) ++ "',\n"
+  ++ "},"
+  ++ showNmis cx
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"
