diff --git a/SOURCES/macros.rubygems b/SOURCES/macros.rubygems
index 1043c02..ba1c0a2 100644
--- a/SOURCES/macros.rubygems
+++ b/SOURCES/macros.rubygems
@@ -3,16 +3,21 @@
 %gem_archdir %{_libdir}/gems
 
 # Common gem locations and files.
-%gem_instdir %{gem_dir}/gems/%{gem_name}-%{version}
-%gem_extdir_mri %{gem_archdir}/%{name}/%{gem_name}-%{version}
+%gem_instdir %{gem_dir}/gems/%{gem_name}-%{version}%{?prerelease}
+%gem_extdir_mri %{gem_archdir}/%{name}/%{gem_name}-%{version}%{?prerelease}
 %gem_libdir %{gem_instdir}/lib
-%gem_cache %{gem_dir}/cache/%{gem_name}-%{version}.gem
-%gem_spec %{gem_dir}/specifications/%{gem_name}-%{version}.gemspec
-%gem_docdir %{gem_dir}/doc/%{gem_name}-%{version}
+%gem_cache %{gem_dir}/cache/%{gem_name}-%{version}%{?prerelease}.gem
+%gem_spec %{gem_dir}/specifications/%{gem_name}-%{version}%{?prerelease}.gemspec
+%gem_docdir %{gem_dir}/doc/%{gem_name}-%{version}%{?prerelease}
 
-# Install gem into appropriate directory.
-# -n<gem_file>      Overrides gem file name for installation.
-# -d<install_dir>   Set installation directory.
+
+# %gem_install - Install gem into appropriate directory.
+#
+# Usage: %gem_install [options]
+#
+# -n <gem_file>      Overrides gem file name for installation.
+# -d <install_dir>   Set installation directory.
+#
 %gem_install(d:n:) \
 mkdir -p %{-d*}%{!?-d:.%{gem_dir}} \
 \
@@ -24,9 +29,10 @@ gem install \\\
         --bindir .%{_bindir} \\\
         --force \\\
         --document=ri,rdoc \\\
-        %{-n*}%{!?-n:%{gem_name}-%{version}.gem} \
+        %{-n*}%{!?-n:%{gem_name}-%{version}%{?prerelease}.gem} \
 %{nil}
 
+
 # For rubygems packages we want to filter out any provides caused by private
 # libs in %%{gem_archdir}.
 #
@@ -35,3 +41,91 @@ gem install \\\
 %rubygems_default_filter %{expand: \
 %global __provides_exclude_from %{?__provides_exclude_from:%{__provides_exclude_from}|}^%{gem_extdir_mri}/.*\\\\.so$ \
 }
+
+
+# The 'read' command in gemspec_add _depand gemspec_remove_dep macros is not
+# essential, but it is usefull to make the sript appear in build log.
+
+
+# %gemspec_add_dep - Add dependency into .gemspec.
+#
+# Usage: %gemspec_add_dep -g <gem> [options] [requirements]
+#
+# Add dependency named <gem> to .gemspec file. The macro adds runtime
+# dependency by default. The [requirements] argument can be used to specify
+# the dependency constraints more precisely. It is expected to be valid Ruby
+# code.
+#
+# -s <gemspec_file>   Overrides the default .gemspec location.
+# -d                  Add development dependecy.
+#
+%gemspec_add_dep(g:s:d) \
+read -d '' gemspec_add_dep_script << 'EOR' || : \
+  gemspec_file = '%{-s*}%{!?-s:./%{gem_name}.gemspec}' \
+  \
+  name = '%{-g*}' \
+  requirements = %{*}%{!?1:nil} \
+  \
+  type = :%{!?-d:runtime}%{?-d:development} \
+  \
+  spec = Gem::Specification.load(gemspec_file) \
+  abort("#{gemspec_file} is not accessible.") unless spec \
+  \
+  dep = spec.dependencies.detect { |d| d.type == type && d.name == name } \
+  if dep \
+    dep.requirement.concat requirements \
+  else \
+    spec.public_send "add_#{type}_dependency", name, requirements \
+  end \
+  File.write gemspec_file, spec.to_ruby \
+EOR\
+echo "$gemspec_add_dep_script" | ruby \
+unset -v gemspec_add_dep_script \
+%{nil}
+
+
+# %gemspec_remove_dep - Remove dependency from .gemspec.
+#
+# Usage: %gemspec_remove_dep -g <gem> [options] [requirements]
+#
+# Remove dependency named <gem> from .gemspec file. The macro removes runtime
+# dependency by default. The [requirements] argument can be used to specify
+# the dependency constraints more precisely. It is expected to be valid Ruby
+# code. The macro fails if these specific requirements can't be removed.
+#
+# -s <gemspec_file>   Overrides the default .gemspec location.
+# -d                  Remove development dependecy.
+#
+%gemspec_remove_dep(g:s:d) \
+read -d '' gemspec_remove_dep_script << 'EOR' || : \
+  gemspec_file = '%{-s*}%{!?-s:./%{gem_name}.gemspec}' \
+  \
+  name = '%{-g*}' \
+  requirements = %{*}%{!?1:nil} \
+  \
+  type = :%{!?-d:runtime}%{?-d:development} \
+  \
+  spec = Gem::Specification.load(gemspec_file) \
+  abort("#{gemspec_file} is not accessible.") unless spec \
+  \
+  dep = spec.dependencies.detect { |d| d.type == type && d.name == name } \
+  if dep \
+    if requirements \
+      requirements = Gem::Requirement.create(requirements).requirements \
+      requirements.each do |r| \
+        unless dep.requirement.requirements.reject! { |dependency_requirements| dependency_requirements == r } \
+          abort("Requirement '#{r.first} #{r.last}' was not possible to remove for dependency '#{dep}'!") \
+        end \
+      end \
+      spec.dependencies.delete dep if dep.requirement.requirements.empty? \
+    else \
+      spec.dependencies.delete dep \
+    end \
+  else \
+    abort("Dependency '#{name}' was not found!") \
+  end \
+  File.write gemspec_file, spec.to_ruby \
+EOR\
+echo "$gemspec_remove_dep_script" | ruby \
+unset -v gemspec_remove_dep_script \
+%{nil}
diff --git a/SOURCES/ruby-2.2.4-check-length-of-selected-NPN-protocol.patch b/SOURCES/ruby-2.2.4-check-length-of-selected-NPN-protocol.patch
new file mode 100644
index 0000000..98463c2
--- /dev/null
+++ b/SOURCES/ruby-2.2.4-check-length-of-selected-NPN-protocol.patch
@@ -0,0 +1,102 @@
+From 950fd771fb8908968cce67a38fdde69ef0cd2b80 Mon Sep 17 00:00:00 2001
+From: nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
+Date: Fri, 27 Nov 2015 21:24:30 +0000
+Subject: [PATCH] merge revision(s) 52227,52228: [Backport #11369]
+
+	* ext/openssl/ossl_ssl.c (ssl_npn_select_cb): explicitly raise error
+	  in ext/openssl instead of OpenSSL itself because LibreSSL
+	  silently truncate the selected protocol name by casting the length
+	  from int to unsigned char. [Bug #11369]
+	  Patch by Jeremy Evans <merch-redmine@jeremyevans.net>
+
+
+git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@52772 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
+---
+ ChangeLog              |  8 ++++++++
+ ext/openssl/ossl_ssl.c | 43 +++++++++++++++++++++++++++++++------------
+ 2 files changed, 39 insertions(+), 12 deletions(-)
+
+diff --git a/ChangeLog b/ChangeLog
+index 161a4b9..160143c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -36,6 +36,14 @@
+ 
+ 	* ext/dl/handle.c (rb_dlhandle_sym): ditto
+ 
++Sat Nov 28 06:12:32 2015  NARUSE, Yui  <naruse@ruby-lang.org>
++
++	* ext/openssl/ossl_ssl.c (ssl_npn_select_cb): explicitly raise error
++	  in ext/openssl instead of OpenSSL itself because LibreSSL
++	  silently truncate the selected protocol name by casting the length
++	  from int to unsigned char. [Bug #11369]
++	  Patch by Jeremy Evans <merch-redmine@jeremyevans.net>
++
+ Tue Aug 18 22:00:12 2015  SHIBATA Hiroshi  <hsbt@ruby-lang.org>
+ 
+ 	* lib/rubygems.rb: bump version to 2.0.14.1. this version fixed
+diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
+index 75e26a4..6e777c9 100644
+--- a/ext/openssl/ossl_ssl.c
++++ b/ext/openssl/ossl_ssl.c
+@@ -601,29 +601,48 @@ ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
+ }
+ 
+ static int
+-ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
++ssl_npn_select_cb_common(VALUE cb, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen)
+ {
+-    int i = 0;
+-    VALUE sslctx_obj, cb, protocols, selected;
+-
+-    sslctx_obj = (VALUE) arg;
+-    cb = rb_iv_get(sslctx_obj, "@npn_select_cb");
+-    protocols = rb_ary_new();
++    VALUE selected;
++    long len;
++    unsigned char l;
++    VALUE protocols = rb_ary_new();
+ 
+     /* The format is len_1|proto_1|...|len_n|proto_n\0 */
+-    while (in[i]) {
+-	VALUE protocol = rb_str_new((const char *) &in[i + 1], in[i]);
++    while (l = *in++) {
++	VALUE protocol;
++	if (l > inlen) {
++	    ossl_raise(eSSLError, "Invalid protocol name list");
++	}
++	protocol = rb_str_new((const char *)in, l);
+ 	rb_ary_push(protocols, protocol);
+-	i += in[i] + 1;
++	in += l;
++	inlen -= l;
+     }
+ 
+     selected = rb_funcall(cb, rb_intern("call"), 1, protocols);
+     StringValue(selected);
+-    *out = (unsigned char *) StringValuePtr(selected);
+-    *outlen = RSTRING_LENINT(selected);
++    len = RSTRING_LEN(selected);
++    if (len < 1 || len >= 256) {
++	ossl_raise(eSSLError, "Selected protocol name must have length 1..255");
++    }
++    *out = (unsigned char *)RSTRING_PTR(selected);
++    *outlen = (unsigned char)len;
+ 
+     return SSL_TLSEXT_ERR_OK;
+ }
++
++static int
++ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
++{
++    VALUE sslctx_obj, cb;
++
++    sslctx_obj = (VALUE) arg;
++    cb = rb_iv_get(sslctx_obj, "@npn_select_cb");
++
++    return ssl_npn_select_cb_common(cb, (const unsigned char **)out, outlen, in, inlen);
++}
++
+ #endif
+ 
+ /* This function may serve as the entry point to support further
diff --git a/SOURCES/ruby-2.2.6-fix-parsing-protocol-list.patch b/SOURCES/ruby-2.2.6-fix-parsing-protocol-list.patch
new file mode 100644
index 0000000..99f20ce
--- /dev/null
+++ b/SOURCES/ruby-2.2.6-fix-parsing-protocol-list.patch
@@ -0,0 +1,63 @@
+From 30238f96081e47178237e58f5229850514858fd3 Mon Sep 17 00:00:00 2001
+From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
+Date: Tue, 15 Nov 2016 06:33:36 +0000
+Subject: [PATCH] merge revision(s) 53064: [Backport #11810]
+
+	* ext/openssl/ossl_ssl.c (ssl_npn_select_cb_common): fix parsing
+	  protocol list.
+	  The protocol list from OpenSSL is not null-terminated.
+	  patched by Kazuki Yamaguchi [Bug #11810] [ruby-core:72082]
+
+
+git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@56798 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
+---
+ ChangeLog              |  7 +++++++
+ ext/openssl/ossl_ssl.c | 17 +++++++----------
+ 2 files changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/ChangeLog b/ChangeLog
+index cae6e73..f8f303e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Tue Nov 15 15:29:36 2016  NARUSE, Yui  <naruse@ruby-lang.org>
++
++	* ext/openssl/ossl_ssl.c (ssl_npn_select_cb_common): fix parsing
++	  protocol list.
++	  The protocol list from OpenSSL is not null-terminated.
++	  patched by Kazuki Yamaguchi [Bug #11810] [ruby-core:72082]
++
+ Thu Feb 25 19:49:31 2016  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+ 
+ 	* ext/socket/socket.c (sock_gethostname): support unlimited size
+diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
+index 0da1eb1..5b00cb7 100644
+--- a/ext/openssl/ossl_ssl.c
++++ b/ext/openssl/ossl_ssl.c
+@@ -605,19 +605,16 @@ ssl_npn_select_cb_common(VALUE cb, const unsigned char **out, unsigned char *out
+ {
+     VALUE selected;
+     long len;
+-    unsigned char l;
+     VALUE protocols = rb_ary_new();
++    unsigned char l;
++    const unsigned char *in_end = in + inlen;
+ 
+-    /* The format is len_1|proto_1|...|len_n|proto_n\0 */
+-    while (l = *in++) {
+-	VALUE protocol;
+-	if (l > inlen) {
+-	    ossl_raise(eSSLError, "Invalid protocol name list");
+-	}
+-	protocol = rb_str_new((const char *)in, l);
+-	rb_ary_push(protocols, protocol);
++    /* assume OpenSSL verifies this format */
++    /* The format is len_1|proto_1|...|len_n|proto_n */
++    while (in < in_end) {
++	l = *in++;
++	rb_ary_push(protocols, rb_str_new((const char *)in, l));
+ 	in += l;
+-	inlen -= l;
+     }
+ 
+     selected = rb_funcall(cb, rb_intern("call"), 1, protocols);
diff --git a/SPECS/ruby.spec b/SPECS/ruby.spec
index c8baad9..7742f3c 100644
--- a/SPECS/ruby.spec
+++ b/SPECS/ruby.spec
@@ -26,7 +26,7 @@
 %endif
 
 
-%global release 29
+%global release 30
 %{!?release_string:%global release_string %{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}}
 
 %global rubygems_version 2.0.14.1
@@ -190,6 +190,13 @@ Patch34: ruby-2.2.0-fix-missing-declaration-of-rb_frame_last_func.patch
 # https://bugs.ruby-lang.org/issues/11877
 # https://bugzilla.redhat.com/show_bug.cgi?id=1343945
 Patch35: ruby-2.1.0-fix-hostname-size-limit.patch
+# Fix test_npn_protocol_selection_ary and test_npn_protocol_selection_enum
+# failures with newest openssl.
+# https://bugzilla.redhat.com/show_bug.cgi?id=1416123
+# https://bugs.ruby-lang.org/issues/11369
+Patch36: ruby-2.2.4-check-length-of-selected-NPN-protocol.patch
+# https://bugs.ruby-lang.org/issues/11810
+Patch37: ruby-2.2.6-fix-parsing-protocol-list.patch
 
 Requires: %{name}-libs%{?_isa} = %{version}-%{release}
 Requires: ruby(rubygems) >= %{rubygems_version}
@@ -467,6 +474,8 @@ Tcl/Tk interface for the object-oriented scripting language Ruby.
 %patch33 -p1
 %patch34 -p1
 %patch35 -p1
+%patch36 -p1
+%patch37 -p1
 
 # Provide an example of usage of the tapset:
 cp -a %{SOURCE3} .
@@ -577,6 +586,9 @@ mkdir -p %{buildroot}%{_libdir}/gems/%{name}/json-%{json_version}/lib
 mv %{buildroot}%{ruby_libdir}/json* %{buildroot}%{gem_dir}/gems/json-%{json_version}/lib
 mv %{buildroot}%{ruby_libarchdir}/json/ %{buildroot}%{_libdir}/gems/%{name}/json-%{json_version}/lib/
 mv %{buildroot}%{gem_dir}/specifications/default/json-%{json_version}.gemspec %{buildroot}%{gem_dir}/specifications
+ln -s %{gem_dir}/gems/json-%{json_version}/lib/json.rb %{buildroot}%{ruby_libdir}/json.rb
+ln -s %{gem_dir}/gems/json-%{json_version}/lib/json %{buildroot}%{ruby_libdir}/json
+ln -s %{_libdir}/gems/%{name}/json-%{json_version}/lib/json/ %{buildroot}%{ruby_libarchdir}/json
 
 mkdir -p %{buildroot}%{gem_dir}/gems/minitest-%{minitest_version}/lib
 mv %{buildroot}%{ruby_libdir}/minitest %{buildroot}%{gem_dir}/gems/minitest-%{minitest_version}/lib
@@ -648,6 +660,12 @@ make runruby TESTRUN_SCRIPT=%{SOURCE9}
 # https://bugs.ruby-lang.org/issues/11434
 sed -i "/test_try_/ a\      return;" test/mkmf/test_flags.rb
 
+# Recent glibc seqfaults when executed with LD_PRELOAD => hardcode
+# the check result for now.
+# https://bugzilla.redhat.com/show_bug.cgi?id=1428369#c6
+sed -i '/combination(STRINGS, STRINGS) {|str, salt|/i\    strict_crypt = true' \
+  test/ruby/test_m17n_comb.rb
+
 # Allow MD5 in OpenSSL.
 # https://bugs.ruby-lang.org/issues/9154
 OPENSSL_ENABLE_MD5_VERIFY=1 make check TESTS="-v $DISABLE_TESTS"
@@ -918,6 +936,8 @@ OPENSSL_ENABLE_MD5_VERIFY=1 make check TESTS="-v $DISABLE_TESTS"
 %{gem_dir}/specifications/io-console-%{io_console_version}.gemspec
 
 %files -n rubygem-json
+%{ruby_libdir}/json*
+%{ruby_libarchdir}/json*
 %{_libdir}/gems/%{name}/json-%{json_version}
 %{gem_dir}/gems/json-%{json_version}
 %{gem_dir}/specifications/json-%{json_version}.gemspec
@@ -944,6 +964,16 @@ OPENSSL_ENABLE_MD5_VERIFY=1 make check TESTS="-v $DISABLE_TESTS"
 %{ruby_libdir}/tkextlib
 
 %changelog
+* Wed Mar 01 2017 Vít Ondruch <vondruch@redhat.com> - 2.0.0.648-30
+- Fix test_npn_protocol_selection_ary and test_npn_protocol_selection_enum
+  failures with newest openssl.
+  Resolves: rhbz#1416123
+- Add gemspec_add_dep and gemspec_remove_dep macros.
+- Extend 'gem_' macros for pre-release version support.
+  Resolves: rhbz#1397390
+- Make symlinks for json gem.
+  Resolves: rhbz#1308992
+
 * Wed Jun 08 2016 Pavel Valena <pvalena@redhat.com> - 2.0.0.648-29
 - Fix hostname size limit
   Resolves: rhbz#1343945