diff --git a/make-osx-bundle.py b/make-osx-bundle.py
new file mode 100755
index 0000000..fe46c7d
--- /dev/null
+++ b/make-osx-bundle.py
@@ -0,0 +1,393 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#
+# Loosely based on original bash-version by Sebastian Schlingmann (based, again, on a OSX application bundler
+# by Thomas Keller).
+#
+
+import sys, os, string, re, shutil, plistlib, tempfile, exceptions, datetime, tarfile
+from subprocess import Popen, PIPE
+from optparse import OptionParser
+
+import platform
+
+if platform.system () != 'Darwin':
+  print "This script is indended to be run only on OSX platform"
+  exit (1)
+
+MIN_SUPPORTED_VERSION="10.10"
+
+current_version = tuple(int(i) for i in platform.mac_ver()[0].split('.')[0:2])
+min_supported_version = tuple(int(i) for i in MIN_SUPPORTED_VERSION.split('.')[0:2])
+
+if current_version < min_supported_version:
+  print "This script is indended to be run only on OSX >= %s platform" % MIN_SUPPORTED_VERSION
+  exit (1)
+
+options = None
+
+def gitrev():
+  return os.popen('git describe').read()[:-1]
+
+def codesign(path):
+  '''Call the codesign executable.'''
+
+  if hasattr(path, 'isalpha'):
+    path = (path,)
+
+  for p in path:
+    p = Popen(('codesign', '-vvvv', '--deep', '--force', '--sign', options.codesign, p))
+    retval = p.wait()
+    if retval != 0:
+      return retval
+  return 0
+
+class AppBundle(object):
+
+  def __init__(self, bundle, version, binary):
+    shutil.copytree (src = binary, dst = bundle, symlinks = True)
+
+    self.framework_path = ''
+    self.handled_libs = {}
+    self.bundle = bundle
+    self.version = version
+    self.infopath = os.path.join(os.path.abspath(bundle), 'Contents', 'Info.plist')
+    self.infoplist = plistlib.readPlist(self.infopath)
+    self.binary = os.path.join(os.path.abspath(bundle), 'Contents', 'MacOS', self.infoplist['CFBundleExecutable'])
+    print ' * Preparing AppBundle'
+
+  def is_system_lib(self, lib):
+    '''
+      Is the library a system library, meaning that we should not include it in our bundle?
+    '''
+    if lib.startswith('/System/Library/'):
+      return True
+    if lib.startswith('/usr/lib/'):
+      return True
+
+    return False
+
+  def is_dylib(self, lib):
+    '''
+      Is the library a dylib?
+    '''
+    return lib.endswith('.dylib')
+
+  def get_framework_base(self, fw):
+    '''
+      Extracts the base .framework bundle path from a library in an abitrary place in a framework.
+    '''
+    paths = fw.split('/')
+    for i, str in enumerate(paths):
+      if str.endswith('.framework'):
+        return '/'.join(paths[:i+1])
+    return None
+
+  def is_framework(self, lib):
+    '''
+      Is the library a framework?
+    '''
+    return bool(self.get_framework_base(lib))
+
+  def get_binary_libs(self, path):
+    '''
+      Get a list of libraries that we depend on.
+    '''
+    m = re.compile('^\t(.*)\ \(.*$')
+    libs = Popen(['otool', '-L', path], stdout=PIPE).communicate()[0]
+    libs = string.split(libs, '\n')
+    ret = []
+    bn = os.path.basename(path)
+    for line in libs:
+      g = m.match(line)
+      if g is not None:
+        lib = g.groups()[0]
+        if lib != bn:
+          ret.append(lib)
+    return ret
+
+  def handle_libs(self):
+    '''
+      Copy non-system libraries that we depend on into our bundle, and fix linker
+      paths so they are relative to our bundle.
+    '''
+    print ' * Taking care of libraries'
+
+    # Does our fwpath exist?
+    fwpath = os.path.join(os.path.abspath(self.bundle), 'Contents', 'Frameworks')
+    if not os.path.exists(fwpath):
+      os.mkdir(fwpath)
+
+    self.handle_binary_libs()
+
+  def handle_binary_libs(self, macho=None, loader_path=None):
+    '''
+      Fix up dylib depends for a specific binary.
+    '''
+    # Does our fwpath exist already? If not, create it.
+    if not self.framework_path:
+      self.framework_path = self.bundle + '/Contents/Frameworks'
+      if not os.path.exists(self.framework_path):
+        os.mkdir(self.framework_path)
+      else:
+        shutil.rmtree(self.framework_path)
+        os.mkdir(self.framework_path)
+
+    # If we weren't explicitly told which binary to operate on, pick the
+    # bundle's default executable from its property list.
+    if macho is None:
+      macho = os.path.abspath(self.binary)
+    else:
+      macho = os.path.abspath(macho)
+
+    print "Processing [%s]" % macho
+      
+    libs = self.get_binary_libs(macho)
+
+    for lib in libs:
+
+      # Skip system libraries
+      if self.is_system_lib(lib):
+        continue
+
+      # Frameworks are 'special'.
+      if self.is_framework(lib):
+        fw_path = self.get_framework_base(lib)
+        basename = os.path.basename(fw_path)
+        name = basename.split('.framework')[0]
+        rel = basename + '/' + name
+
+        abs = self.framework_path + '/' + rel
+
+        if not basename in self.handled_libs:
+          dst = self.framework_path + '/' + basename
+          print "COPY ", fw_path, dst
+          shutil.copytree(fw_path, dst, symlinks=True)
+          if name.startswith('Qt'):
+            os.remove(dst + '/' + name + '.prl')
+            os.remove(dst + '/Headers')
+            shutil.rmtree(dst + '/Versions/Current/Headers')
+
+          os.chmod(abs, 0755)
+          os.system('install_name_tool -id "@executable_path/../Frameworks/%s" "%s"' % (rel, abs))
+          self.handled_libs[basename] = True
+          self.handle_binary_libs(abs)
+
+        os.chmod(macho, 0755)
+        print 'install_name_tool -change "%s" "@executable_path/../Frameworks/%s" "%s"' % (lib, rel, macho)
+        os.system('install_name_tool -change "%s" "@executable_path/../Frameworks/%s" "%s"' % (lib, rel, macho))
+
+      # Regular dylibs
+      else:
+        basename = os.path.basename(lib)
+        rel = basename
+
+        if not basename in self.handled_libs:
+          if lib.startswith('@loader_path'):
+            copypath = lib.replace('@loader_path', loader_path)
+          else:
+            copypath = lib
+
+          print "COPY ", copypath
+          shutil.copy(copypath, self.framework_path  + '/' + basename)
+
+          abs = self.framework_path + '/' + rel
+          os.chmod(abs, 0755)
+          os.system('install_name_tool -id "@executable_path/../Frameworks/%s" "%s"' % (rel, abs))
+          self.handled_libs[basename] = True
+          self.handle_binary_libs(abs, loader_path=os.path.dirname(lib) if loader_path is None else loader_path)
+
+        print 'install_name_tool -change "%s" "@executable_path/../Frameworks/%s" "%s"' % (lib, rel, macho)
+        os.chmod(macho, 0755)
+        os.system('install_name_tool -change "%s" "@executable_path/../Frameworks/%s" "%s"' % (lib, rel, macho))
+
+  def copy_resources(self, rsrcs):
+    '''
+      Copy needed resources into our bundle.
+    '''
+    print ' * Copying needed resources'
+    rsrcpath = os.path.join(self.bundle, 'Contents', 'Resources')
+    if not os.path.exists(rsrcpath):
+      os.mkdir(rsrcpath)
+
+    # Copy resources already in the bundle
+    for rsrc in rsrcs:
+      b = os.path.basename(rsrc)
+      if os.path.isdir(rsrc):
+        shutil.copytree(rsrc, os.path.join(rsrcpath, b), symlinks=True)
+      elif os.path.isfile(rsrc):
+        shutil.copy(rsrc, os.path.join(rsrcpath, b))
+
+    return
+
+  def copy_qt_plugins(self):
+    '''
+      Copy over any needed Qt plugins.
+    '''
+
+    print ' * Copying Qt and preparing plugins'
+
+    src = os.popen('qmake -query QT_INSTALL_PLUGINS').read().strip()
+    dst = os.path.join(self.bundle, 'Contents', 'QtPlugins')
+    shutil.copytree(src, dst, symlinks=False)
+
+    top = dst
+    files = {}
+
+    def cb(arg, dirname, fnames):
+      if dirname == top:
+        return
+      files[os.path.basename(dirname)] = fnames
+
+    os.path.walk(top, cb, None)
+
+    exclude = ( 'phonon_backend', 'designer', 'script' )
+
+    for dir, files in files.items():
+      absdir = dst + '/' + dir
+      if dir in exclude:
+        shutil.rmtree(absdir)
+        continue
+      for file in files:
+        abs = absdir + '/' + file
+        if file.endswith('_debug.dylib'):
+          os.remove(abs)
+        else:
+          os.system('install_name_tool -id "%s" "%s"' % (file, abs))
+          self.handle_binary_libs(abs)
+
+  def set_min_macosx_version(self, version):
+    '''
+      Set the minimum version of Mac OS X version that this App will run on.
+    '''
+    print ' * Setting minimum Mac OS X version to: %s' % (version)
+    self.infoplist['LSMinimumSystemVersion'] = version
+
+  def done(self):
+    plistlib.writePlist(self.infoplist, self.infopath)
+    print ' * Done!'
+    print ''
+
+class FolderObject(object):
+  class Exception(exceptions.Exception):
+    pass
+
+  def __init__(self):
+    self.tmp = tempfile.mkdtemp()
+
+  def copy(self, src, dst='/'):
+    '''
+      Copy a file or directory into foler
+    '''
+    asrc = os.path.abspath(src)
+
+    if dst[0] != '/':
+      raise self.Exception
+
+    # Determine destination
+    if dst[-1] == '/':
+      adst = os.path.abspath(self.tmp + '/' + dst + os.path.basename(src))
+    else:
+      adst = os.path.abspath(self.tmp + '/' + dst)
+
+    if os.path.isdir(asrc):
+      print ' * Copying directory: %s' % os.path.basename(asrc)
+      shutil.copytree(asrc, adst, symlinks=True)
+    elif os.path.isfile(asrc):
+      print ' * Copying file: %s' % os.path.basename(asrc)
+      shutil.copy(asrc, adst)
+
+  def symlink(self, src, dst):
+    '''
+      Create a symlink inside the folder
+    '''
+    asrc = os.path.abspath(src)
+    adst = self.tmp + '/' + dst
+    print " * Creating symlink %s" % os.path.basename(asrc)
+    os.symlink(asrc, adst)
+
+  def mkdir(self, name):
+    '''
+      Create a directory inside the folder.
+    '''
+    print ' * Creating directory %s' % os.path.basename(name)
+    adst = self.tmp + '/' + name
+    os.makedirs(adst)
+
+class DiskImage(FolderObject):
+
+  def __init__(self, filename, volname):
+    FolderObject.__init__(self)
+    print ' * Preparing to create diskimage'
+    self.filename = filename
+    self.volname = volname
+
+  def create(self):
+    '''
+      Create the disk image
+    '''
+    print ' * Creating disk image. Please wait...'
+    if os.path.exists(self.filename):
+      shutil.rmtree(self.filename)
+    p = Popen(['hdiutil', 'create',
+              '-srcfolder', self.tmp,
+              '-format', 'UDBZ',
+              '-volname', self.volname,
+              self.filename])
+
+    retval = p.wait()
+    print ' * Removing temporary directory.'
+    shutil.rmtree(self.tmp)
+    print ' * Done!'
+
+
+if __name__ == '__main__':
+  parser = OptionParser()
+  parser.add_option('-r', '--release', dest='release', help='Build a release. This determines the version number of the release.')
+  parser.add_option('-s', '--snapshot', dest='snapshot', help='Build a snapshot release. This determines the \'snapshot version\'.')
+  parser.add_option('-g', '--git', dest='git', help='Build a snapshot release. Use the git revision number as the \'snapshot version\'.', action='store_true', default=False)
+  parser.add_option('--codesign', dest='codesign', help='Identity to use for code signing. (If not set, no code signing will occur)')
+
+  options, args = parser.parse_args()
+
+  # Release
+  if options.release:
+    ver = options.release
+  # Snapshot
+  elif options.snapshot or options.git:
+    if not options.git:
+      ver = options.snapshot
+    else:
+      ver = gitrev()
+  else:
+    print 'ERROR: Neither snapshot or release selected. Bailing.'
+    parser.print_help ()
+    sys.exit(1)
+
+  # Do the finishing touches to our Application bundle before release
+  shutil.rmtree('build/%s/NDN.app' % (MIN_SUPPORTED_VERSION), ignore_errors=True)
+  a = AppBundle('build/%s/NDN.app' % (MIN_SUPPORTED_VERSION), ver, 'build/NFD Control Center.app')
+  a.copy_qt_plugins()
+  a.handle_libs()
+  a.copy_resources(['qt.conf'])
+  a.set_min_macosx_version('%s.0' % MIN_SUPPORTED_VERSION)
+  a.done()
+
+  # Sign our binaries, etc.
+  if options.codesign:
+    print ' * Signing binaries with identity `%s\'' % options.codesign
+    binaries = (
+      'build/%s/ChronoChat.app' % (MIN_SUPPORTED_VERSION),
+    )
+
+    codesign(binaries)
+    print ''
+
+  # Create diskimage
+  title = "NDN-%s-%s" % (ver, MIN_SUPPORTED_VERSION)
+  fn = "build/%s.dmg" % title
+  d = DiskImage(fn, title)
+  d.symlink('/Applications', '/Applications')
+  d.copy('build/%s/NDN.app' % MIN_SUPPORTED_VERSION, '/NDN.app')
+  d.create()
