diff --git a/lib/cmock_generator_plugin_ignore_arg.rb b/lib/cmock_generator_plugin_ignore_arg.rb
new file mode 100644
index 0000000..e71b707
--- /dev/null
+++ b/lib/cmock_generator_plugin_ignore_arg.rb
@@ -0,0 +1,47 @@
+class CMockGeneratorPluginIgnoreArg
+  attr_reader :priority
+  attr_accessor :config, :utils, :unity_helper, :ordered
+
+  def initialize(config, utils)
+    @config       = config
+    @ordered      = @config.enforce_strict_ordering
+    @utils        = utils
+    @unity_helper = @utils.helpers[:unity_helper]
+    @priority     = 10
+  end
+
+  def instance_typedefs(function)
+    lines = ""
+    function[:args].each do |arg|
+      lines << "  int IgnoreArg_#{arg[:name]};\n"
+    end
+    lines
+  end
+
+  def mock_function_declarations(function)
+    lines = ""
+    function[:args].each do |arg|
+      lines << "#define #{function[:name]}_IgnoreArg_#{arg[:name]}()"
+      lines << " #{function[:name]}_CMockIgnoreArg_#{arg[:name]}(__LINE__)\n"
+      lines << "void #{function[:name]}_CMockIgnoreArg_#{arg[:name]}(UNITY_LINE_TYPE cmock_line);\n"
+    end
+    lines
+  end
+
+  def mock_interfaces(function)
+    lines = []
+    func_name = function[:name]
+    function[:args].each do |arg|
+      arg_name = arg[:name]
+      arg_type = arg[:type]
+      lines << "void #{function[:name]}_CMockIgnoreArg_#{arg[:name]}(UNITY_LINE_TYPE cmock_line)\n"
+      lines << "{\n"
+      lines << "  CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = " +
+        "cmock_call_instance = (CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.#{func_name}_CallInstance));\n"
+      lines << "  UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"#{arg_name} IgnoreArg called before Expect on '#{func_name}'.\");\n"
+      lines << "  cmock_call_instance->IgnoreArg_#{arg_name} = 1;\n"
+      lines << "}\n\n"
+    end
+    lines
+  end
+end
diff --git a/lib/cmock_generator_plugin_return_thru_ptr.rb b/lib/cmock_generator_plugin_return_thru_ptr.rb
new file mode 100644
index 0000000..f94d2be
--- /dev/null
+++ b/lib/cmock_generator_plugin_return_thru_ptr.rb
@@ -0,0 +1,81 @@
+class CMockGeneratorPluginReturnThruPtr
+  attr_reader :priority
+  attr_accessor :config, :utils, :unity_helper, :ordered
+
+  def initialize(config, utils)
+    @config       = config
+    @ordered      = @config.enforce_strict_ordering
+    @utils        = utils
+    @unity_helper = @utils.helpers[:unity_helper]
+    @priority     = 9
+    @ignore_arg   = @config.plugins.include? :ignore_arg
+  end
+
+  def instance_typedefs(function)
+    lines = ""
+    function[:args].each do |arg|
+      if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?])
+        lines << "  int ReturnThruPtr_#{arg[:name]}_Used;\n"
+        lines << "  #{arg[:type]} ReturnThruPtr_#{arg[:name]}_Val;\n"
+        lines << "  int ReturnThruPtr_#{arg[:name]}_Size;\n"
+      end
+    end
+    lines
+  end
+
+  def mock_function_declarations(function)
+    lines = ""
+    function[:args].each do |arg|
+      if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?])
+        lines << "#define #{function[:name]}_ReturnThruPtr_#{arg[:name]}(#{arg[:name]})"
+        lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(*#{arg[:name]}))\n"
+        lines << "#define #{function[:name]}_ReturnArrayThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_len)"
+        lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, cmock_len * sizeof(*#{arg[:name]}))\n"
+        lines << "#define #{function[:name]}_ReturnMemThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_size)"
+        lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, cmock_size)\n"
+        lines << "void #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg[:name]}, int cmock_size);\n"
+      end
+    end
+    lines
+  end
+
+  def mock_interfaces(function)
+    lines = []
+    func_name = function[:name]
+    function[:args].each do |arg|
+      arg_name = arg[:name]
+      arg_type = arg[:type]
+      if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?])
+        lines << "void #{func_name}_CMockReturnMemThruPtr_#{arg_name}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg_name}, int cmock_size)\n"
+        lines << "{\n"
+        lines << "  CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = " +
+          "cmock_call_instance = (CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.#{func_name}_CallInstance));\n"
+        lines << "  UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"#{arg_name} ReturnThruPtr called before Expect on '#{func_name}'.\");\n"
+        if (@ignore_arg)
+          lines << "  cmock_call_instance->IgnoreArg_#{arg_name} = 1;\n"
+        end
+        lines << "  cmock_call_instance->ReturnThruPtr_#{arg_name}_Used = 1;\n"
+        lines << "  cmock_call_instance->ReturnThruPtr_#{arg_name}_Val = #{arg_name};\n"
+        lines << "  cmock_call_instance->ReturnThruPtr_#{arg_name}_Size = cmock_size;\n"
+        lines << "}\n\n"
+      end
+    end
+    lines
+  end
+
+  def mock_implementation(function)
+    lines = []
+    function[:args].each do |arg|
+      arg_name = arg[:name]
+      arg_type = arg[:type]
+      if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?])
+        lines << "  if (cmock_call_instance->ReturnThruPtr_#{arg_name}_Used)\n"
+        lines << "  {\n"
+        lines << "    memcpy(#{arg_name}, cmock_call_instance->ReturnThruPtr_#{arg_name}_Val,\n"
+        lines << "      cmock_call_instance->ReturnThruPtr_#{arg_name}_Size);\n"
+        lines << "  }\n"
+      end
+    end
+    lines
+  end
+end
diff --git a/lib/cmock_generator_utils.rb b/lib/cmock_generator_utils.rb
index 043ff2d..a4d2f69 100644
--- a/lib/cmock_generator_utils.rb
+++ b/lib/cmock_generator_utils.rb
@@ -14,6 +14,8 @@ class CMockGeneratorUtils
     @ordered      = @config.enforce_strict_ordering
     @arrays       = @config.plugins.include? :array
     @cexception   = @config.plugins.include? :cexception
+    @return_thru_ptr = @config.plugins.include? :return_thru_ptr
+    @ignore_arg   = @config.plugins.include? :ignore_arg
     @treat_as     = @config.treat_as
 	  @helpers = helpers
     
@@ -42,6 +44,8 @@ class CMockGeneratorUtils
   def code_add_an_arg_expectation(arg, depth=1) 
     lines =  code_assign_argument_quickly("cmock_call_instance->Expected_#{arg[:name]}", arg)
     lines << "  cmock_call_instance->Expected_#{arg[:name]}_Depth = #{arg[:name]}_Depth;\n" if (@arrays and (depth.class == String))
+    lines << "  cmock_call_instance->IgnoreArg_#{arg[:name]} = 0;\n" if (@ignore_arg)
+    lines << "  cmock_call_instance->ReturnThruPtr_#{arg[:name]}_Used = 0;\n" if (@return_thru_ptr and ptr_or_str?(arg[:type]) and not arg[:const?])
     lines
   end
   
@@ -84,94 +88,115 @@ class CMockGeneratorUtils
     end
   end
   
+  def ptr_or_str?(arg_type)
+    return (arg_type.include? '*' or
+            @treat_as.fetch(arg_type, "").include? '*')
+  end
+
   #private ######################
   
   def lookup_expect_type(function, arg)
     c_type     = arg[:type]
     arg_name   = arg[:name]
     expected   = "cmock_call_instance->Expected_#{arg_name}" 
+    ignore     = "cmock_call_instance->IgnoreArg_#{arg_name}"
     unity_func = if ((arg[:ptr?]) and ((c_type =~ /\*\*/) or (@ptr_handling == :compare_ptr)))
                    ['UNITY_TEST_ASSERT_EQUAL_PTR', '']
                  else
                    (@helpers.nil? or @helpers[:unity_helper].nil?) ? ["UNITY_TEST_ASSERT_EQUAL",''] : @helpers[:unity_helper].get_helper(c_type)
                  end
     unity_msg  = "Function '#{function[:name]}' called with unexpected value for argument '#{arg_name}'."
-    return c_type, arg_name, expected, unity_func[0], unity_func[1], unity_msg
+    return c_type, arg_name, expected, ignore, unity_func[0], unity_func[1], unity_msg
   end
   
   def code_verify_an_arg_expectation_with_no_arrays(function, arg)
-    c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
+    c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
+    lines = ""
+    lines << "  if (!#{ignore})\n" if @ignore_arg
+    lines << "  {\n"
     case(unity_func)
       when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
         c_type_local = c_type.gsub(/\*$/,'')
-        return "  UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
+        lines << "    UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
       when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
-        [ "  if (#{pre}#{expected} == NULL)",
-          "    { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
-          "  else",
-          "    { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, \"#{unity_msg}\"); }\n"].join("\n")
+        lines << "    if (#{pre}#{expected} == NULL)\n"
+        lines << "      { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n"
+        lines << "    else\n"
+        lines << "      { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, \"#{unity_msg}\"); }\n"
       when /_ARRAY/
-        [ "  if (#{pre}#{expected} == NULL)",
-          "    { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
-          "  else",
-          "    { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, \"#{unity_msg}\"); }\n"].join("\n")
+        lines << "    if (#{pre}#{expected} == NULL)\n"
+        lines << "      { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n"
+        lines << "    else\n"
+        lines << "      { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, \"#{unity_msg}\"); }\n"
       else
-        return "  #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" 
-    end  
+        lines << "    #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" 
+    end
+    lines << "  }\n"
+    lines
   end
   
   def code_verify_an_arg_expectation_with_normal_arrays(function, arg)
-    c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
+    c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
     depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
+    lines = ""
+    lines << "  if (!#{ignore})\n" if @ignore_arg
+    lines << "  {\n"
     case(unity_func)
       when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
         c_type_local = c_type.gsub(/\*$/,'')
-        return "  UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
+        lines << "    UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
       when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY"
-        [ "  if (#{pre}#{expected} == NULL)",
-          "    { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
-          "  else",
-          "    { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
+        lines << "    if (#{pre}#{expected} == NULL)\n"
+        lines << "      { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n"
+        lines << "    else\n"
+        lines << "      { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"
       when /_ARRAY/
         if (pre == '&')
-          "  #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
+          lines << "    #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
         else
-          [ "  if (#{pre}#{expected} == NULL)",
-            "    { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
-            "  else",
-            "    { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
+          lines << "    if (#{pre}#{expected} == NULL)\n"
+          lines << "      { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n"
+          lines << "    else\n"
+          lines << "      { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"
         end
       else
-        return "  #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" 
+        lines << "    #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" 
     end
+    lines << "  }\n"
+    lines
   end
   
   def code_verify_an_arg_expectation_with_smart_arrays(function, arg)
-    c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
+    c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
     depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
+    lines = ""
+    lines << "  if (!#{ignore})\n" if @ignore_arg
+    lines << "  {\n"
     case(unity_func)
       when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
         c_type_local = c_type.gsub(/\*$/,'')
-        return "  UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
+        lines << "  UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
       when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY"
-        [ "  if (#{pre}#{expected} == NULL)",
-          "    { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
-          ((depth_name != 1) ? "  else if (#{depth_name} == 0)\n    { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }" : nil),
-          "  else",
-          "    { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
+        lines << "    if (#{pre}#{expected} == NULL)\n"
+        lines << "      { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n"
+        lines << ((depth_name != 1) ? "    else if (#{depth_name} == 0)\n      { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }\n" : "")
+        lines << "    else\n"
+        lines << "      { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"
       when /_ARRAY/
         if (pre == '&')
-          "  #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
+          lines << "    #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
         else
-          [ "  if (#{pre}#{expected} == NULL)",
-            "    { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
-            ((depth_name != 1) ? "  else if (#{depth_name} == 0)\n    { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }" : nil),
-            "  else",
-            "    { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
+          lines << "    if (#{pre}#{expected} == NULL)\n"
+          lines << "      { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n"
+          lines << ((depth_name != 1) ? "  else if (#{depth_name} == 0)\n      { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }\n" : "")
+          lines << "    else\n"
+          lines << "      { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"
         end
       else
-        return "  #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" 
+        lines << "    #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n" 
     end
+    lines << "  }\n"
+    lines
   end
   
-end
\ No newline at end of file
+end
diff --git a/src/cmock.c b/src/cmock.c
index e26243a..40a4ef6 100644
--- a/src/cmock.c
+++ b/src/cmock.c
@@ -147,6 +147,24 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index
 }
 
 //-------------------------------------------------------
+// CMock_Guts_MemEndOfChain
+//-------------------------------------------------------
+CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index)
+{
+  CMOCK_MEM_INDEX_TYPE index = root_index;
+  CMOCK_MEM_INDEX_TYPE next_index;
+        
+  for (next_index = root_index;
+       next_index != CMOCK_GUTS_NONE;
+       next_index = CMock_Guts_MemNext(index))
+  {
+    index = next_index;
+  }
+
+  return index;
+}
+
+//-------------------------------------------------------
 // CMock_GetAddressFor
 //-------------------------------------------------------
 void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index)
diff --git a/src/cmock.h b/src/cmock.h
index 084a828..4dcfc1f 100644
--- a/src/cmock.h
+++ b/src/cmock.h
@@ -20,6 +20,7 @@
 CMOCK_MEM_INDEX_TYPE  CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size);
 CMOCK_MEM_INDEX_TYPE  CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index);
 CMOCK_MEM_INDEX_TYPE  CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index);
+CMOCK_MEM_INDEX_TYPE  CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index);
 
 void*                 CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index);
 
