diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ImmutableCompositeFunction.h b/Code/Mantid/Framework/API/inc/MantidAPI/ImmutableCompositeFunction.h
index 7cbf7f4b2f6ea9e0590e4e04970add7c55cd7359..24495861b32bf950093c1898bba38c268a086b80 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/ImmutableCompositeFunction.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/ImmutableCompositeFunction.h
@@ -6,6 +6,8 @@
 //----------------------------------------------------------------------
 #include "MantidAPI/CompositeFunction.h"
 
+#include <map>
+
 namespace Mantid
 {
 namespace API
@@ -49,11 +51,38 @@ public:
   virtual std::string name()const {return "ImmutableCompositeFunction";}
   /// Writes itself into a string
   std::string asString()const;
+  /// Set i-th parameter
+  void setParameter(size_t i, const double& value, bool explicitlySet = true)
+  {CompositeFunction::setParameter(i, value, explicitlySet);}
+  /// Set i-th parameter description
+  void setParameterDescription(size_t i, const std::string& description)
+  {CompositeFunction::setParameterDescription(i, description);}
+  /// Set parameter by name.
+  void setParameter(const std::string& name, const double& value, bool explicitlySet = true);
+  /// Set description of parameter by name.
+  void setParameterDescription(const std::string& name, const std::string& description);
+  /// Get i-th parameter
+  double getParameter(size_t i)const { return CompositeFunction::getParameter( i ); }
+  /// Get parameter by name.
+  double getParameter(const std::string& name)const;
+  /// Returns the index of parameter name
+  size_t parameterIndex(const std::string& name)const;
+  /// Returns the name of parameter i
+  std::string parameterName(size_t i)const;
 
 protected:
 
-  // make it protected
+  /// Make it protected
   using CompositeFunction::addFunction;
+  /// Overload addFunction to take a bare pointer
+  void addFunction(IFunction* fun);
+  /// Define an alias for a parameter
+  void setAlias(const std::string& parName, const std::string& alias);
+
+private:
+
+  /// Keep paramater aliases
+  std::map< std::string, size_t > m_alias;
 
 };
 
diff --git a/Code/Mantid/Framework/API/src/ImmutableCompositeFunction.cpp b/Code/Mantid/Framework/API/src/ImmutableCompositeFunction.cpp
index 7f13f9add0b03fd2f2cf1afd057c4d34049b95d1..bc0cdf58ec5f5a410fa4a04d82a9647a094f0e1a 100644
--- a/Code/Mantid/Framework/API/src/ImmutableCompositeFunction.cpp
+++ b/Code/Mantid/Framework/API/src/ImmutableCompositeFunction.cpp
@@ -4,6 +4,8 @@
 #include "MantidKernel/Exception.h"
 #include "MantidAPI/ImmutableCompositeFunction.h"
 
+#include <algorithm>
+
 namespace Mantid
 {
 namespace API
@@ -11,13 +13,117 @@ namespace API
 
 using std::size_t;
 
+  //-----------------------------------------------------------------------------------------------
   /**
    * Overridden method creates an initialization string which makes it look like a 
    * siple function.
    */
   std::string ImmutableCompositeFunction::asString()const
   {
-    return "";
+    return IFunction::asString();
+  }
+
+  /**
+   * A convenience method to add a new function.
+   * @param fun @@ A pointer to a newly created function.
+   */
+  void ImmutableCompositeFunction::addFunction(IFunction* fun)
+  {
+    addFunction( IFunction_sptr( fun ) );
+  }
+
+  /**
+   * Set parameter by name.
+   * @param name :: An alias or a name in CompositeFunction's style: f#.name
+   * @param value :: A new parameter value.
+   * @param explicitlySet :: The explicitly set flag.
+   */
+  void ImmutableCompositeFunction::setParameter(const std::string& name, const double& value, bool explicitlySet)
+  {
+    auto alias = m_alias.find( name );
+    if ( alias != m_alias.end() )
+    {
+      CompositeFunction::setParameter( alias->second, value, explicitlySet );
+    }
+    else
+    {
+      CompositeFunction::setParameter( name, value, explicitlySet );
+    }
+  }
+
+  /**
+   * Set description of parameter by name.
+   * @param name :: An alias or a name in CompositeFunction's style: f#.name
+   * @param description :: A parameter description.
+   */
+  void ImmutableCompositeFunction::setParameterDescription(const std::string& name, const std::string& description)
+  {
+    auto alias = m_alias.find( name );
+    if ( alias != m_alias.end() )
+    {
+      CompositeFunction::setParameterDescription( alias->second, description );
+    }
+    else
+    {
+      CompositeFunction::setParameterDescription( name, description );
+    }
+  }
+
+  /**
+   * Get parameter by name.
+   * @param name :: An alias or a name in CompositeFunction's style: f#.name
+   * @return :: The parameter value.
+   */
+  double ImmutableCompositeFunction::getParameter(const std::string& name)const
+  {
+    auto alias = m_alias.find( name );
+    if ( alias != m_alias.end() )
+    {
+      return CompositeFunction::getParameter( alias->second );
+    }
+    return CompositeFunction::getParameter( name );
+  }
+
+  /**
+   * Returns the index of parameter name
+   * @param name :: An alias or a name in CompositeFunction's style: f#.name
+   */
+  size_t ImmutableCompositeFunction::parameterIndex(const std::string& name)const
+  {
+    auto alias = m_alias.find( name );
+    if ( alias != m_alias.end() )
+    {
+      return alias->second;
+    }
+    return CompositeFunction::parameterIndex( name );
+  }
+
+  /**
+   * Returns the alias or name of parameter i
+   */
+  std::string ImmutableCompositeFunction::parameterName(size_t i)const
+  {
+    for(auto alias = m_alias.begin(); alias != m_alias.end(); ++alias)
+    {
+      if ( alias->second == i ) return alias->first;
+    }
+    return CompositeFunction::parameterName( i );
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * Define an alias for a parameter. Use this method only after all member functions have been added.
+   * @param parName :: Fully qualified parameter name.
+   * @param alias :: An alias for the parameter.
+   */
+  void ImmutableCompositeFunction::setAlias(const std::string& parName, const std::string& alias)
+  {
+    // make sure the alias is unique
+    if ( m_alias.count(alias) > 0 )
+    {
+      throw Kernel::Exception::ExistsError("ImmutableCompositeFunction",alias);
+    }
+    m_alias[alias] = CompositeFunction::parameterIndex( parName );
   }
 
 } // namespace API
diff --git a/Code/Mantid/Framework/API/test/ImmutableCompositeFunctionTest.h b/Code/Mantid/Framework/API/test/ImmutableCompositeFunctionTest.h
index 142c6d9440f27ace3a53702954901d2b371c52b8..07d0e8bd465e178468e69a2603c5dff4e0336ee4 100644
--- a/Code/Mantid/Framework/API/test/ImmutableCompositeFunctionTest.h
+++ b/Code/Mantid/Framework/API/test/ImmutableCompositeFunctionTest.h
@@ -6,15 +6,16 @@
 #include "MantidAPI/ImmutableCompositeFunction.h"
 #include "MantidAPI/ParamFunction.h"
 #include "MantidAPI/IFunction1D.h"
+#include "MantidAPI/FunctionFactory.h"
 
 using namespace Mantid;
 using namespace Mantid::API;
 
 
-class Linear: public ParamFunction, public IFunction1D
+class ImmutableCompositeFunctionTest_Linear: public ParamFunction, public IFunction1D
 {
 public:
-  Linear()
+  ImmutableCompositeFunctionTest_Linear()
   {
     declareParameter("a");
     declareParameter("b");
@@ -33,7 +34,6 @@ public:
   }
   void functionDeriv1D(Jacobian* out, const double* xValues, const size_t nData)
   {
-    //throw Mantid::Kernel::Exception::NotImplementedError("");
     for(size_t i=0;i<nData;i++)
     {
       out->set(static_cast<int>(i),0,1.);
@@ -48,6 +48,67 @@ class ImmutableCompositeFunctionTest_Function: public ImmutableCompositeFunction
 public:
   ImmutableCompositeFunctionTest_Function(): ImmutableCompositeFunction()
   {
+    IFunction* fun1 = new ImmutableCompositeFunctionTest_Linear;
+    fun1->setParameter( "a", 1.0 );
+    fun1->setParameter( "b", 2.0 );
+    addFunction( fun1 );
+
+    IFunction* fun2 = new ImmutableCompositeFunctionTest_Linear;
+    fun2->setParameter( "a", 3.0 );
+    fun2->setParameter( "b", 4.0 );
+    addFunction( fun2 );
+
+    setAlias("f0.a", "a1");
+    setAlias("f0.b", "b1");
+    setAlias("f1.a", "a2");
+    setAlias("f1.b", "b2");
+  }
+  std::string name()const {return "ImmutableCompositeFunctionTest_Function";}
+};
+
+DECLARE_FUNCTION(ImmutableCompositeFunctionTest_Function);
+
+class ImmutableCompositeFunctionTest_FunctionThrow: public ImmutableCompositeFunction
+{
+public:
+  ImmutableCompositeFunctionTest_FunctionThrow(): ImmutableCompositeFunction()
+  {
+    IFunction* fun1 = new ImmutableCompositeFunctionTest_Linear;
+    fun1->setParameter( "a", 1.0 );
+    fun1->setParameter( "b", 2.0 );
+    addFunction( fun1 );
+
+    IFunction* fun2 = new ImmutableCompositeFunctionTest_Linear;
+    fun2->setParameter( "a", 3.0 );
+    fun2->setParameter( "b", 4.0 );
+    addFunction( fun2 );
+
+    setAlias("f0.a", "a1");
+    setAlias("f0.b", "b1");
+    setAlias("f1.a", "a1"); // repeated alias
+    setAlias("f1.b", "b2");
+  }
+};
+
+class ImmutableCompositeFunctionTest_FunctionThrow1: public ImmutableCompositeFunction
+{
+public:
+  ImmutableCompositeFunctionTest_FunctionThrow1(): ImmutableCompositeFunction()
+  {
+    IFunction* fun1 = new ImmutableCompositeFunctionTest_Linear;
+    fun1->setParameter( "a", 1.0 );
+    fun1->setParameter( "b", 2.0 );
+    addFunction( fun1 );
+
+    IFunction* fun2 = new ImmutableCompositeFunctionTest_Linear;
+    fun2->setParameter( "a", 3.0 );
+    fun2->setParameter( "b", 4.0 );
+    addFunction( fun2 );
+
+    setAlias("f0.a", "a1");
+    setAlias("f0.b", "b1");
+    setAlias("f1.a", "a2");
+    setAlias("f1.c", "b2"); // name doesn't exist
   }
 };
 
@@ -57,7 +118,174 @@ public:
   void testAdd()
   {
     ImmutableCompositeFunctionTest_Function icf;
+    TS_ASSERT_EQUALS( icf.nFunctions(), 2 );
+    TS_ASSERT_EQUALS( icf.getParameter(0), 1.0 );
+    TS_ASSERT_EQUALS( icf.getParameter(1), 2.0 );
+    TS_ASSERT_EQUALS( icf.getParameter(2), 3.0 );
+    TS_ASSERT_EQUALS( icf.getParameter(3), 4.0 );
+  }
+  
+  void testFactoryCreate()
+  {
+    auto fun = FunctionFactory::Instance().createInitialized("name=ImmutableCompositeFunctionTest_Function");
+    TS_ASSERT( fun );
+    TS_ASSERT_EQUALS( fun->nParams(), 4 );
+    TS_ASSERT_EQUALS( fun->getParameter(0), 1.0 );
+    TS_ASSERT_EQUALS( fun->getParameter(1), 2.0 );
+    TS_ASSERT_EQUALS( fun->getParameter(2), 3.0 );
+    TS_ASSERT_EQUALS( fun->getParameter(3), 4.0 );
   }
+
+  void testFactoryInitialize()
+  {
+    std::string ini = "name=ImmutableCompositeFunctionTest_Function,a1=7.0,b1=8.0,a2=9.0,b2=0";
+    auto fun = FunctionFactory::Instance().createInitialized(ini);
+    TS_ASSERT( fun );
+    TS_ASSERT_EQUALS( fun->nParams(), 4 );
+    TS_ASSERT_EQUALS( fun->getParameter(0), 7.0 );
+    TS_ASSERT_EQUALS( fun->getParameter(1), 8.0 );
+    TS_ASSERT_EQUALS( fun->getParameter(2), 9.0 );
+    TS_ASSERT_EQUALS( fun->getParameter(3), 0.0 );
+  }
+
+  void testParameterAlias()
+  {
+    ImmutableCompositeFunctionTest_Function icf;
+
+    TS_ASSERT_EQUALS( icf.getParameter("a1"), 1.0 );
+    TS_ASSERT_EQUALS( icf.getParameter("b1"), 2.0 );
+    TS_ASSERT_EQUALS( icf.getParameter("a2"), 3.0 );
+    TS_ASSERT_EQUALS( icf.getParameter("b2"), 4.0 );
+
+    TS_ASSERT_EQUALS( icf.getParameter("f0.a"), 1.0 );
+    TS_ASSERT_EQUALS( icf.getParameter("f0.b"), 2.0 );
+    TS_ASSERT_EQUALS( icf.getParameter("f1.a"), 3.0 );
+    TS_ASSERT_EQUALS( icf.getParameter("f1.b"), 4.0 );
+  }
+
+  void testSetParameter()
+  {
+    ImmutableCompositeFunctionTest_Function icf;
+
+    icf.setParameter("a1", 11.0);
+    icf.setParameter("b1", 12.0);
+    icf.setParameter("a2", 13.0);
+    icf.setParameter("b2", 14.0);
+
+    TS_ASSERT_EQUALS( icf.getParameter(0), 11.0 );
+    TS_ASSERT_EQUALS( icf.getParameter(1), 12.0 );
+    TS_ASSERT_EQUALS( icf.getParameter(2), 13.0 );
+    TS_ASSERT_EQUALS( icf.getParameter(3), 14.0 );
+
+  }
+
+  void testSetParameterDescription()
+  {
+    ImmutableCompositeFunctionTest_Function icf;
+
+    icf.setParameterDescription("a1", "First a parameter");
+    icf.setParameterDescription("b1", "First b parameter");
+    icf.setParameterDescription("a2", "Second a parameter");
+    icf.setParameterDescription("f1.b", "Second b parameter");
+
+    TS_ASSERT_EQUALS( icf.parameterDescription(0), "First a parameter" );
+    TS_ASSERT_EQUALS( icf.parameterDescription(1), "First b parameter" );
+    TS_ASSERT_EQUALS( icf.parameterDescription(2), "Second a parameter" );
+    TS_ASSERT_EQUALS( icf.parameterDescription(3), "Second b parameter" );
+  }
+
+  void testParameterIndex()
+  {
+    ImmutableCompositeFunctionTest_Function icf;
+
+    TS_ASSERT_EQUALS( icf.parameterIndex("a1"), 0 );
+    TS_ASSERT_EQUALS( icf.parameterIndex("b1"), 1 );
+    TS_ASSERT_EQUALS( icf.parameterIndex("a2"), 2 );
+    TS_ASSERT_EQUALS( icf.parameterIndex("b2"), 3 );
+
+    TS_ASSERT_EQUALS( icf.parameterIndex("f0.a"), 0 );
+    TS_ASSERT_EQUALS( icf.parameterIndex("f0.b"), 1 );
+    TS_ASSERT_EQUALS( icf.parameterIndex("f1.a"), 2 );
+    TS_ASSERT_EQUALS( icf.parameterIndex("f1.b"), 3 );
+  }
+
+  void testParameterName()
+  {
+    ImmutableCompositeFunctionTest_Function icf;
+
+    TS_ASSERT_EQUALS( icf.parameterName(0), "a1" );
+    TS_ASSERT_EQUALS( icf.parameterName(1), "b1" );
+    TS_ASSERT_EQUALS( icf.parameterName(2), "a2" );
+    TS_ASSERT_EQUALS( icf.parameterName(3), "b2" );
+  }
+
+  void testParameterAliasUnique()
+  {
+    TS_ASSERT_THROWS(ImmutableCompositeFunctionTest_FunctionThrow icf, Mantid::Kernel::Exception::ExistsError);
+  }
+
+  void testSetAliasThrowsIfNameDoesntExist()
+  {
+    TS_ASSERT_THROWS(ImmutableCompositeFunctionTest_FunctionThrow1 icf, std::invalid_argument);
+  }
+
+  void testAddTies()
+  {
+    ImmutableCompositeFunctionTest_Function icf;
+
+    icf.addTies("b2=b1,a2=a1/5");
+    TS_ASSERT( !icf.getTie( 0 ) );
+    TS_ASSERT( !icf.getTie( 1 ) );
+    TS_ASSERT( icf.getTie( 2 ) );
+    TS_ASSERT( icf.getTie( 3 ) );
+
+    icf.applyTies();
+
+    TS_ASSERT_EQUALS( icf.getParameter(0), 1.0 );
+    TS_ASSERT_EQUALS( icf.getParameter(1), 2.0 );
+    TS_ASSERT_EQUALS( icf.getParameter(2), 0.2 );
+    TS_ASSERT_EQUALS( icf.getParameter(3), 2.0 );
+  }
+
+  // BoundaryConstraint isn't defined (it's in CurveFitting) so this test doesn't work
+  void xtestConstraints()
+  {
+    ImmutableCompositeFunctionTest_Function icf;
+
+    icf.addConstraints("0 < b1 < 5");
+    TS_ASSERT( ! icf.getConstraint( 0 ) );
+    TS_ASSERT( ! icf.getConstraint( 1 ) );
+    TS_ASSERT(   icf.getConstraint( 2 ) );
+    TS_ASSERT( ! icf.getConstraint( 3 ) );
+  }
+
+  void testAsString()
+  {
+    ImmutableCompositeFunctionTest_Function icf;
+
+    icf.setParameter(0, 11.0 );
+    icf.setParameter(1, 12.0 );
+    icf.setParameter(2, 13.0 );
+    icf.setParameter(3, 14.0 );
+
+    icf.addTies("b2=b1,a2=a1/5");
+    icf.applyTies();
+
+    TS_ASSERT_EQUALS( icf.asString(), "name=ImmutableCompositeFunctionTest_Function,a1=11,b1=12,a2=2.2,b2=12,ties=(a2=a1/5,b2=b1)" );
+
+    auto fun = FunctionFactory::Instance().createInitialized( icf.asString() );
+    TS_ASSERT( fun );
+    TS_ASSERT_EQUALS( fun->nParams(), 4 );
+    TS_ASSERT_EQUALS( fun->getParameter(0), 11.0 );
+    TS_ASSERT_EQUALS( fun->getParameter(1), 12.0 );
+    TS_ASSERT_EQUALS( fun->getParameter(2), 2.2 );
+    TS_ASSERT_EQUALS( fun->getParameter(3), 12.0 );
+    TS_ASSERT( ! fun->getTie( 0 ) );
+    TS_ASSERT( ! fun->getTie( 1 ) );
+    TS_ASSERT(   fun->getTie( 2 ) );
+    TS_ASSERT(   fun->getTie( 3 ) );
+  }
+
 };
 
 #endif /*IMMUTABLECOMPOSITEFUNCTIONTEST_H_*/