You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@reef.apache.org by we...@apache.org on 2015/01/29 21:42:58 UTC

[14/31] incubator-reef git commit: [REEF-97] Add the REEF.NET code base

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/InjectorImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/InjectorImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/InjectorImpl.cs
new file mode 100644
index 0000000..6144f3e
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/InjectorImpl.cs
@@ -0,0 +1,1091 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Annotations;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class InjectorImpl : IInjector
+    {
+        private static readonly Logger LOGGER = Logger.GetLogger(typeof(InjectorImpl));
+
+        IDictionary<INamedParameterNode, object> namedParameterInstances = new MonotonicTreeMap<INamedParameterNode, object>();
+        private ICsClassHierarchy classHierarchy;
+        private IConfiguration configuration;
+        readonly IDictionary<IClassNode, Object> instances = new MonotonicTreeMap<IClassNode, Object>();
+        private Aspect aspect;
+        private readonly ISet<IInjectionFuture<object>> pendingFutures = new HashSet<IInjectionFuture<object>>();
+
+        static readonly InjectionPlan BUILDING = new BuildingInjectionPlan(null); //TODO anonymous class
+
+
+        private bool concurrentModificationGuard = false;
+
+        private void AssertNotConcurrent()
+        {
+            if (concurrentModificationGuard)
+            {
+                //TODO
+                //throw new ConcurrentModificationException("Detected attempt to use Injector from within an injected constructor!");
+            }
+        }
+        public InjectorImpl(IConfiguration c)
+        {
+            this.configuration = c;
+            this.classHierarchy = (ICsClassHierarchy)c.GetClassHierarchy();
+        }
+
+        public object InjectFromPlan(InjectionPlan plan)
+        {
+            if (!plan.IsFeasible())
+            {
+                var ex = new InjectionException("Cannot inject " + plan.GetNode().GetFullName() + ": "
+                    + plan.ToCantInjectString());
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+            }
+
+            if (plan.IsAmbiguous())
+            {
+                var ex = new InjectionException("Cannot inject " + plan.GetNode().GetFullName() + " "
+                    + plan.ToCantInjectString());
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+            }
+
+            if (plan is InjectionFuturePlan)
+            {
+                InjectionFuturePlan fut = (InjectionFuturePlan)plan;
+                INode node = fut.GetNode();
+                string key = node.GetFullName();
+                try
+                {
+                    Type t = null;
+                    Type nodeType = classHierarchy.ClassForName(node.GetFullName());
+                    
+                    if (node is IClassNode)
+                    {
+                        t = nodeType; 
+                    }
+                    else if (node is INamedParameterNode)
+                    {
+                        var nn = (INamedParameterNode)node;
+                        t = classHierarchy.ClassForName(nn.GetFullArgName());
+                        if (nn.IsSet())
+                        {
+                            t = typeof (ISet<>).MakeGenericType(new Type[] {t});
+                        }
+                    }
+                    else
+                    {
+                        var ex = new ApplicationException("Unexpected node type. Wanted ClassNode or NamedParameterNode.  Got: " + node);
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                    }
+                    
+                    //Java - InjectionFuture<?> ret = new InjectionFuture<>(this, javaNamespace.classForName(fut.getNode().getFullName()));
+                    //C# - InjectionFuture<object> ret = new InjectionFutureImpl<object>(this, classHierarchy.ClassForName(fut.GetNode().GetFullName()));
+                    //We cannot simply create an object from generic with object as <T>
+                    //typeof(InjectionFutureImpl<>).MakeGenericType(t) will get the InjectionFutureImpl generic Type with <T> as t 
+                    //for ClassNode, t is the Type of the class, for NamedParamterNode, t is the Type of the argument
+                    //we then use reflection to invoke the constructor
+                    //To retain generic argument information??                   
+                    Type injectionFuture = typeof (InjectionFutureImpl<>).MakeGenericType(t);
+                    var constructor = injectionFuture.GetConstructor(new Type[] { typeof(IInjector), typeof(Type) });
+                    IInjectionFuture<object> ret = (IInjectionFuture<object>)constructor.Invoke(new object[] { this, nodeType }); 
+
+                    pendingFutures.Add(ret);
+                    return ret;
+                }
+                catch (TypeLoadException e)
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new InjectionException("Could not get class for " + key), LOGGER); 
+                }
+            }
+            else if (plan.GetNode() is IClassNode && null != GetCachedInstance((IClassNode)plan.GetNode()))
+            {
+                return GetCachedInstance((IClassNode)plan.GetNode());
+            }
+            else if (plan is CsInstance)
+            {
+                // TODO: Must be named parameter node.  Check.
+                //      throw new IllegalStateException("Instance from plan not in Injector's set of instances?!?");
+                return ((CsInstance)plan).instance;
+            }
+            else if (plan is Constructor)
+            {
+                Constructor constructor = (Constructor)plan;
+                object[] args = new object[constructor.GetArgs().Length];
+                InjectionPlan[] argPlans = constructor.GetArgs();
+
+                for (int i = 0; i < argPlans.Length; i++)
+                {
+                    args[i] = InjectFromPlan(argPlans[i]);
+                }
+
+                try
+                {
+                    concurrentModificationGuard = true;
+                    object ret = null;
+                    try
+                    {
+                        IConstructorDef def = (IConstructorDef)constructor.GetConstructorDef();
+                        ConstructorInfo c = GetConstructor(def);
+
+                        if (aspect != null)
+                        {
+                            ret = aspect.Inject(def, c, args);
+                        }
+                        else
+                        {
+                            ret = c.Invoke(args);
+                        }
+                    }
+                    catch (ArgumentException e)
+                    {
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                        StringBuilder sb = new StringBuilder("Internal Tang error?  Could not call constructor " + constructor.GetConstructorDef() + " with arguments [");
+                        foreach (Object o in args)
+                        {
+                            sb.Append("\n\t" + o);
+                        }
+                        sb.Append("]");
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(sb.ToString(), e), LOGGER); 
+                    }
+                    if (ret is IExternalConstructor<object>)
+                    {
+                        ret = ((IExternalConstructor<object>)ret).NewInstance();
+                    }
+                    instances.Add(constructor.GetNode(), ret);
+                    return ret;
+                }
+                catch (TargetInvocationException e)
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new InjectionException("Could not invoke constructor: " + plan, e), LOGGER);
+                }
+                finally
+                {
+                    concurrentModificationGuard = false; 
+                }
+            }
+            else if (plan is Subplan)
+            {
+                Subplan ambiguous = (Subplan)plan;
+                return InjectFromPlan(ambiguous.GetDelegatedPlan());
+            }
+            else if (plan is SetInjectionPlan)
+            {
+                SetInjectionPlan setPlan = (SetInjectionPlan)plan;
+                INode n = setPlan.GetNode();
+                string typeOfSet = null;
+
+                // TODO: This doesn't work for sets of generics (e.g., Set<Foo<int>>
+                // because GetFullName and GetFullArgName strip generic info).
+                if (n is INamedParameterNode)
+                {
+                    INamedParameterNode np = (INamedParameterNode)n;
+                    typeOfSet = np.GetFullArgName();
+                }
+                else if (n is IClassNode)
+                {
+                    typeOfSet = n.GetFullName();
+                }
+                else
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Unknown node type :" + n.ToString()), LOGGER);
+                }
+
+                Type t = classHierarchy.ClassForName(typeOfSet);
+                // MakeGenericType(t = int: MonotonicHashSet<> -> MonotonicHashSet<int>
+                // Get constructor: MonotonicHashSet<int> -> public MonotonicHashSet<int>() { ... }
+                // Invoke: public MonotonicHashSet<int> -> new MonotonicHashSet<int>()
+
+                object ret = typeof(MonotonicHashSet<>).MakeGenericType(t).GetConstructor(new Type[] { }).Invoke(new object[] { }); //(this, classHierarchy.ClassForName(fut.GetNode().GetFullName()));
+
+                MethodInfo mf = ret.GetType().GetMethod("Add");
+
+                foreach (InjectionPlan subplan in setPlan.GetEntryPlans())
+                {
+//                    ret.Add(InjectFromPlan(subplan));
+                    mf.Invoke(ret, new object[] {InjectFromPlan(subplan)});
+                }
+                return ret;
+            }
+            else if (plan is ListInjectionPlan)
+            {
+                ListInjectionPlan listPlan = (ListInjectionPlan)plan;
+                INode n = listPlan.GetNode();
+                string typeOfList = null;
+
+                if (n is INamedParameterNode)
+                {
+                    INamedParameterNode np = (INamedParameterNode)n;
+                    typeOfList = np.GetFullArgName();
+                }
+                else if (n is IClassNode)
+                {
+                    typeOfList = n.GetFullName();
+                }
+                else
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Unknown node type :" + n.ToString()), LOGGER);
+                }
+
+                Type t = classHierarchy.ClassForName(typeOfList);
+                object ret = typeof(List<>).MakeGenericType(t).GetConstructor(new Type[] { }).Invoke(new object[] { }); 
+
+                MethodInfo mf = ret.GetType().GetMethod("Add");
+
+                foreach (InjectionPlan subplan in listPlan.GetEntryPlans())
+                {
+                    mf.Invoke(ret, new object[] { InjectFromPlan(subplan) });
+                }
+                return ret;
+            }
+            else
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Unknown plan type: " + plan), LOGGER);
+            }
+            return null; // should never reach here
+        }
+
+        private object GetCachedInstance(IClassNode cn)
+        {
+            if (cn.GetFullName().Equals(ReflectionUtilities.GetAssemblyQualifiedName(typeof(IInjector))))
+                //if (cn.GetFullName().Equals(ReflectionUtilities.NonGenericFullName(typeof(IInjector))))
+            {
+                return this.ForkInjector();// TODO: We should be insisting on injection futures here! .forkInjector();
+            }
+            else
+            {
+                object t = null;
+
+                instances.TryGetValue(cn, out t);
+
+                if (t != null && t is IInjectionFuture<object>)
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Found an injection future in getCachedInstance: " + cn), LOGGER);
+                }
+                return t;
+            }
+        }
+
+        private ConstructorInfo GetConstructor(IConstructorDef constructor)
+        {
+            Type clazz = (Type)this.classHierarchy.ClassForName(constructor.GetClassName());
+            IConstructorArg[] args = constructor.GetArgs().ToArray();
+            Type[] parameterTypes = new Type[args.Length];
+            for (int i = 0; i < args.Length; i++)
+            {
+                if (args[i].IsInjectionFuture())
+                {
+                    parameterTypes[i] = typeof(IInjectionFuture<>).MakeGenericType(new Type[] { this.classHierarchy.ClassForName(args[i].Gettype()) });
+                }
+                else
+                {
+                    parameterTypes[i] = this.classHierarchy.ClassForName(args[i].Gettype());
+                }
+            }
+
+            ConstructorInfo cons = clazz.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null);
+            //TODO
+            //cons.setAccessible(true);
+
+            if (cons == null)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Failed to look up constructor: " + constructor.ToString()), LOGGER);
+            }
+            return cons;
+        }
+
+        private void BuildInjectionPlan(INode n, IDictionary<INode, InjectionPlan> memo)
+        {
+            if (memo.ContainsKey(n))
+            {
+                InjectionPlan p = null;
+                memo.TryGetValue(n, out p);
+                if (BUILDING == p)
+                {
+                    StringBuilder loopyList = new StringBuilder("[");
+                    foreach (INode node in memo.Keys)
+                    {
+                        InjectionPlan p1 = null;
+                        memo.TryGetValue(node, out p1);
+                        if (p1 == BUILDING)
+                        {
+                            loopyList.Append(" " + node.GetFullName());
+                        }
+                    }
+                    loopyList.Append(" ]");
+                    var ex = new ClassHierarchyException("Detected loopy constructor involving "
+                        + loopyList.ToString());
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                }
+                else
+                {
+                    return;
+                }
+            }
+            memo.Add(n, BUILDING);
+            InjectionPlan ip = null;
+            if (n is INamedParameterNode)
+            {
+                INamedParameterNode np = (INamedParameterNode)n;
+                object boundInstance = ParseBoundNamedParameter(np);
+                object defaultInstance = this.classHierarchy.ParseDefaultValue(np);
+                object instance = boundInstance != null ? boundInstance : defaultInstance;
+
+                if (instance is INode)
+                {
+                    BuildInjectionPlan((INode)instance, memo);
+                    InjectionPlan sp;
+                    memo.TryGetValue((INode)instance, out sp);
+                    ip = new Subplan(n, 0, new InjectionPlan[] { sp });
+                }
+                else if (instance is ISet<object>)
+                {
+                    ISet<object> entries = (ISet<object>)instance;
+                    ip = CreateSetInjectionPlan(n, memo, entries);
+                }
+                else if (instance is ISet<INode>)
+                {
+                    ISet<INode> entries = (ISet<INode>)instance;
+                    ip = CreateSetInjectionPlan(n, memo, entries);
+                }
+                else if (instance is IList<object>)
+                {
+                    IList<object> entries = (IList<object>)instance;
+                    ip = CreateListInjectionPlan(n, memo, entries);
+                }
+                else if (instance is IList<INode>)
+                {
+                    IList<INode> entries = (IList<INode>)instance;
+                    ip = CreateListInjectionPlan(n, memo, entries);
+                }
+                else
+                {
+                    ip = new CsInstance(np, instance);
+                }
+
+            }
+            else if (n is IClassNode)
+            {
+                IClassNode cn = (IClassNode)n;
+
+                // Any (or all) of the next four values might be null; that's fine.
+                object cached = GetCachedInstance(cn);
+                IClassNode boundImpl = this.configuration.GetBoundImplementation(cn);
+                IClassNode defaultImpl = ParseDefaultImplementation(cn);
+                IClassNode ec = this.configuration.GetBoundConstructor(cn);
+
+                ip = BuildClassNodeInjectionPlan(cn, cached, ec, boundImpl, defaultImpl, memo);
+            }
+            else if (n is IPackageNode)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException(
+                    "Request to instantiate Java package as object"), LOGGER);
+            }
+            else
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(
+                    "Type hierarchy contained unknown node type!:" + n), LOGGER);
+            }
+            memo[n] = ip;
+        }
+
+        private InjectionPlan CreateSetInjectionPlan<T>(INode n, IDictionary<INode, InjectionPlan> memo, ISet<T> entries)
+        {
+            ISet<InjectionPlan> plans = new MonotonicHashSet<InjectionPlan>();
+            CreateInjectionPlanForCollectionElements(n, memo, entries, plans);
+            return  new SetInjectionPlan(n, plans);
+        }
+
+        private void CreateInjectionPlanForCollectionElements<T>(INode n, IDictionary<INode, InjectionPlan> memo, ICollection<T> entries, ICollection<InjectionPlan> plans)
+        {
+            foreach (var entry in entries)
+            {
+                if (entry is IClassNode)
+                {
+                    BuildInjectionPlan((IClassNode) entry, memo);
+                    InjectionPlan p2 = null;
+                    memo.TryGetValue((INode) entry, out p2);
+                    if (p2 != null)
+                    {
+                        plans.Add(p2);
+                    }
+                }
+                else
+                {
+                    plans.Add(new CsInstance(n, entry));
+                }
+            }
+        }
+
+        private InjectionPlan CreateListInjectionPlan<T>(INode n, IDictionary<INode, InjectionPlan> memo, IList<T> entries)
+        {
+            IList<InjectionPlan> plans = new List<InjectionPlan>();
+            CreateInjectionPlanForCollectionElements(n, memo, entries, plans);
+            return new ListInjectionPlan(n, plans);
+        }
+
+        private InjectionPlan BuildClassNodeInjectionPlan(IClassNode cn,
+            object cachedInstance,
+            IClassNode externalConstructor,
+            IClassNode boundImpl,
+            IClassNode defaultImpl,
+            IDictionary<INode, InjectionPlan> memo)
+        {
+            if (cachedInstance != null)
+            {
+                return new CsInstance(cn, cachedInstance);
+            }
+            else if (externalConstructor != null)
+            {
+                BuildInjectionPlan(externalConstructor, memo);
+                InjectionPlan ip = null;
+                memo.TryGetValue(externalConstructor, out ip);
+                return new Subplan(cn, 0, new InjectionPlan[] { ip });
+            }
+            else if (boundImpl != null && !cn.Equals(boundImpl))
+            {
+                // We need to delegate to boundImpl, so recurse.
+                BuildInjectionPlan(boundImpl, memo);
+                InjectionPlan ip = null;
+                memo.TryGetValue(boundImpl, out ip);
+                return new Subplan(cn, 0, new InjectionPlan[] { ip });
+            }
+            else if (defaultImpl != null && !cn.Equals(defaultImpl))
+            {
+                BuildInjectionPlan(defaultImpl, memo);
+                InjectionPlan ip = null;
+                memo.TryGetValue(defaultImpl, out ip);
+                return new Subplan(cn, 0, new InjectionPlan[] { ip });
+            }
+            else
+            {
+                // if we're here and there is a bound impl or a default impl,
+                // then we're bound / defaulted to ourselves, so don't add
+                // other impls to the list of things to consider.
+                List<IClassNode> candidateImplementations = new List<IClassNode>();
+                candidateImplementations.Add(cn);
+                List<InjectionPlan> sub_ips = FilterCandidateConstructors(candidateImplementations, memo);
+                if (sub_ips.Count == 1)
+                {
+                    return WrapInjectionPlans(cn, sub_ips, false, -1);
+                }
+               return WrapInjectionPlans(cn, sub_ips, true, -1);
+            }
+        }
+
+        private List<InjectionPlan> FilterCandidateConstructors(
+                List<IClassNode> candidateImplementations,
+                IDictionary<INode, InjectionPlan> memo)
+        {
+            List<InjectionPlan> sub_ips = new List<InjectionPlan>();
+
+            #region each implementation
+            foreach (IClassNode thisCN in candidateImplementations)
+            {
+                List<InjectionPlan> constructors = new List<InjectionPlan>();
+                List<IConstructorDef> constructorList = new List<IConstructorDef>();
+                if (null != this.configuration.GetLegacyConstructor(thisCN))
+                {
+                    constructorList.Add(this.configuration.GetLegacyConstructor(thisCN));
+                }
+
+                foreach (var c in thisCN.GetInjectableConstructors())
+                {
+                    constructorList.Add(c);
+                }
+
+                #region each constructor
+                foreach (IConstructorDef def in constructorList)
+                {
+                    List<InjectionPlan> args = new List<InjectionPlan>();
+                    IConstructorArg[] defArgs = def.GetArgs().ToArray<IConstructorArg>();
+
+                    #region each argument
+                    foreach (IConstructorArg arg in defArgs)
+                    {
+                        if (!arg.IsInjectionFuture())
+                        {
+                            try
+                            {
+                                INode argNode = this.classHierarchy.GetNode(arg.GetName());
+                                BuildInjectionPlan(argNode, memo);
+                                InjectionPlan ip = null;
+                                memo.TryGetValue(argNode, out ip);
+                                args.Add(ip);
+                            }
+                            catch (NameResolutionException e)
+                            {
+                                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+
+                                var ex = new IllegalStateException("Detected unresolvable "
+                                + "constructor arg while building injection plan.  "
+                                + "This should have been caught earlier!", e);
+                                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                            }
+                        }
+                        else
+                        {
+                            try
+                            {
+                                args.Add(new InjectionFuturePlan(this.classHierarchy.GetNode(arg.GetName())));
+                            }
+                            catch (NameResolutionException e)
+                            {
+                                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                                var ex = new IllegalStateException("Detected unresolvable "
+                                + "constructor arg while building injection plan.  "
+                                + "This should have been caught earlier!", e);
+                                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                            }
+                        }
+                    }
+                    #endregion each argument
+
+                    Constructor constructor = new Constructor(thisCN, def, args.ToArray());
+                    constructors.Add(constructor);
+                }
+                #endregion each constructor
+
+                // The constructors are embedded in a lattice defined by
+                // isMoreSpecificThan().  We want to see if, amongst the injectable
+                // plans, there is a unique dominant plan, and select it.
+                // First, compute the set of injectable plans.
+                List<Int32> liveIndices = new List<Int32>();
+                for (int i = 0; i < constructors.Count; i++)
+                {
+                    if (constructors[i].GetNumAlternatives() > 0)
+                    {
+                        liveIndices.Add(i);
+                    }
+                }
+                // Now, do an all-by-all comparison, removing indices that are dominated
+                // by others.
+                int k = -1;
+                for (int i = 0; i < liveIndices.Count; i++)
+                {
+                    for (int j = i + 1; j < liveIndices.Count; j++)
+                    {
+                        IConstructorDef ci = ((Constructor)constructors[(liveIndices[i])]).GetConstructorDef();
+                        IConstructorDef cj = ((Constructor)constructors[(liveIndices[j])]).GetConstructorDef();
+
+                        if (ci.IsMoreSpecificThan(cj)) //ci's arguments is a superset of cj's
+                        {
+                            k = i;
+                        }
+                        else if (cj.IsMoreSpecificThan(ci))
+                        {
+                            k = j;
+                        }
+                    }
+                }
+                if (liveIndices.Count == 1)
+                {
+                    k = 0;
+                }
+                if (constructors.Count > 0)
+                {
+                    sub_ips.Add(WrapInjectionPlans(thisCN, constructors, false, k != -1 ? liveIndices[k] : -1));
+                }
+            }
+            #endregion each implementation
+            return sub_ips;
+        }
+
+
+        private InjectionPlan WrapInjectionPlans(IClassNode infeasibleNode,
+            List<InjectionPlan> list, bool forceAmbiguous, int selectedIndex)
+        {
+            if (list.Count == 0)
+            {
+                return new Subplan(infeasibleNode, new InjectionPlan[] { });
+            }
+            else if ((!forceAmbiguous) && list.Count == 1)
+            {
+                return list[0];
+            }
+            else
+            {
+                return new Subplan(infeasibleNode, selectedIndex, list.ToArray());
+            }
+        }
+
+        private IClassNode ParseDefaultImplementation(IClassNode cn)
+        {
+            if (cn.GetDefaultImplementation() != null)
+            {
+                try
+                {
+                    return (IClassNode)this.classHierarchy.GetNode(cn.GetDefaultImplementation());
+                }
+                catch (NameResolutionException e)
+                {
+                    var ex = new IllegalStateException("After validation, " + cn + " had a bad default implementation named " + cn.GetDefaultImplementation(), e);
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.CaughtAndThrow(ex, Level.Error, LOGGER);
+                }
+            }
+            return null;
+        }
+
+        private object ParseBoundNamedParameter(INamedParameterNode np)
+        {
+            ISet<object> boundSet = this.configuration.GetBoundSet((INamedParameterNode)np);
+            if (boundSet.Count != 0)
+            {
+                ISet<INode> ret3 = new MonotonicSet<INode>();
+                ISet<object> ret2 = new MonotonicSet<object>();
+                return ParseElementsInCollection(np, boundSet, ret3, ret2);
+            }
+
+            IList<object> boundList = this.configuration.GetBoundList((INamedParameterNode)np);
+            if (boundList != null && boundList.Count != 0)
+            {
+                IList<INode> ret3 = new List<INode>();
+                IList<object> ret2 = new List<object>();
+                return ParseElementsInCollection(np, boundList, ret3, ret2);
+            }
+
+            object ret = null;
+            if (namedParameterInstances.ContainsKey(np))
+            {
+                namedParameterInstances.TryGetValue(np, out ret);
+            }
+            else
+            {
+                string value = this.configuration.GetNamedParameter(np);
+                if (value == null)
+                {
+                    ret = null;
+                }
+                else
+                {
+                    try
+                    {
+                        ret = this.classHierarchy.Parse(np, value);
+                        namedParameterInstances.Add(np, ret);
+                    }
+                    catch (BindException e)
+                    {
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.CaughtAndThrow(new IllegalStateException(
+                            "Could not parse pre-validated value", e), Level.Error, LOGGER); 
+                    }
+                }
+            }
+            return ret;
+        }
+
+        private object ParseElementsInCollection(INamedParameterNode np, ICollection<object> boundSet, ICollection<INode> ret3, ICollection<object> ret2)
+        {
+            foreach (object o in boundSet)
+            {
+                if (o is string)
+                {
+                    try
+                    {
+                        var r = this.classHierarchy.Parse(np, (string) o);
+                        if (r is INode)
+                        {
+                            ret3.Add((INode) r);
+                        }
+                        else
+                        {
+                            ret2.Add(r);
+                        }
+                    }
+                    catch (ParseException e)
+                    {
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                        var ex =
+                            new IllegalStateException("Could not parse " + o + " which was passed into " + np +
+                                                      " FIXME: Parsability is not currently checked by bindSetEntry(Node,String)");
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                    }
+                }
+                else if (o is INode)
+                {
+                    var o2 = o as INode;
+                    ret3.Add(o2);
+                }
+                else
+                {
+                    var ex =
+                        new IllegalStateException("Unexpected object " + o +
+                                                  " in bound set.  Should consist of nodes and strings");
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                }
+            }
+            if (ret2.Count > 0 && ret3.Count == 0)
+            {
+                return ret2;
+            }
+            if (ret3.Count > 0 && ret2.Count == 0)
+            {
+                return ret3;
+            }
+            if (ret2.Count > 0 && ret3.Count > 0)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Set contains different types of object"), LOGGER);
+            }
+            return ret2;
+        }
+
+        public object GetInstance(Type iface)
+        {
+            return GetInstance(ReflectionUtilities.GetAssemblyQualifiedName(iface));
+        }
+
+        public T GetInstance<T>() where T : class
+        {
+            return (T)GetInstance(ReflectionUtilities.GetAssemblyQualifiedName(typeof(T)));
+        }
+
+        private void CheckNamedParameter(Type t)
+        {
+            if (ReflectionUtilities.IsAssignableFromIgnoreGeneric(typeof (Name<>), t))
+            {
+                var ex = new InjectionException("GetInstance() called on Name "
+                                             + ReflectionUtilities.GetName(t)
+                                             + " Did you mean to call GetNamedInstance() instead?");
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+            }
+        }
+
+        private object GetInstance(INode node)
+        {
+            InjectionPlan plan = (InjectionPlan)GetInjectionPlan(node);
+            object u = InjectFromPlan(plan);
+
+            while (pendingFutures.Count != 0)
+            {
+                IEnumerator<object> i = pendingFutures.GetEnumerator();
+                i.MoveNext();
+                IInjectionFuture<object> f = (IInjectionFuture<object>)i.Current;
+                pendingFutures.Remove(f);
+                f.Get();
+            }
+            return u;
+        }
+
+        public object GetInstance(string clazz)
+        {
+            CheckNamedParameter(ReflectionUtilities.GetTypeByName(clazz));
+            return GetInstance(classHierarchy.GetNode(clazz));
+        }
+
+        public U GetNamedInstance<T, U>(GenericType<T> clazz) where T : Name<U>
+        {
+            Type t = typeof(T);
+            return (U)GetInstance(classHierarchy.GetNode(t));
+        }
+
+        public U GetNamedInstance<T, U>() where T : Name<U>
+        {
+            Type t = typeof(T);
+            return (U)GetInstance(classHierarchy.GetNode(t));
+        }
+
+        public object GetNamedInstance(Type t)
+        {
+            if (!ReflectionUtilities.IsAssignableFromIgnoreGeneric(typeof (Name<>), t))
+            {
+                var ex = new ApplicationException(string.Format(CultureInfo.CurrentCulture, "The parameter {0} is not inherit from Name<>", t));
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+            }
+            return GetInstance(classHierarchy.GetNode(t));
+        }
+
+        public InjectionPlan GetInjectionPlan(Type name)
+        {
+            return GetInjectionPlan(this.classHierarchy.GetNode(name));
+        }
+
+        public InjectionPlan GetInjectionPlan(INode n)
+        {
+            AssertNotConcurrent();
+            IDictionary<INode, InjectionPlan> memo = new Dictionary<INode, InjectionPlan>();
+            BuildInjectionPlan(n, memo);
+
+            InjectionPlan p = null;
+            memo.TryGetValue(n, out p);
+
+            if (p != null)
+            {
+                return p;
+            }
+            Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new InjectionException("Fail to get injection plan" + n), LOGGER);
+            return null;//this line shouild be not reached as Throw throws exception
+        }
+
+        public bool IsInjectable(string name)
+        {
+            return GetInjectionPlan(this.classHierarchy.GetNode(name)).IsInjectable();
+        }
+
+        public bool IsParameterSet(string name)
+        {
+            InjectionPlan p = GetInjectionPlan(classHierarchy.GetNode(name));
+            return p.IsInjectable();
+        }
+
+        public bool IsInjectable(Type clazz)
+        {
+            AssertNotConcurrent();
+            try
+            {
+                return IsInjectable(ReflectionUtilities.GetAssemblyQualifiedName(clazz));
+            }
+            catch (NameResolutionException e)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Could not round trip " + clazz + " through ClassHierarchy", e), LOGGER);
+                return false;
+            }
+        }
+
+        public bool IsParameterSet(Type name)
+        {
+            return IsParameterSet(ReflectionUtilities.GetAssemblyQualifiedName(name));
+        }
+
+        public void BindAspect(Aspect a)
+        {
+            if (aspect != null)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new BindException("Attempt to re-bind aspect! old=" + aspect + " new=" + a), LOGGER);
+            }
+            aspect = a;
+        }
+
+        public Aspect GetAspect()
+        {
+            return aspect;
+        }
+
+        public IInjector ForkInjector()
+        {
+            try
+            {
+                return ForkInjector(new ConfigurationImpl[0]);
+            }
+            catch (BindException e)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Error in forking injector.", e), LOGGER);
+                return null; 
+            }
+        }
+
+        public IInjector ForkInjector(IConfiguration[] configurations)
+        {
+            InjectorImpl ret;
+            ret = Copy(this, configurations);
+            return ret;
+        }
+
+        private static InjectorImpl Copy(InjectorImpl old, IConfiguration[] configurations)
+        {
+            InjectorImpl injector = null;
+            try
+            {
+                IConfigurationBuilder cb = old.configuration.newBuilder();
+                foreach (IConfiguration c in configurations)
+                {
+                    cb.AddConfiguration(c);
+                }
+                injector = new InjectorImpl(cb.Build());
+            }
+            catch (BindException e)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Unexpected error copying configuration!", e), LOGGER);
+            }
+
+            foreach (IClassNode cn in old.instances.Keys)
+            {
+                if (cn.GetFullName().Equals(ReflectionUtilities.GetAssemblyQualifiedName(typeof(IInjector)))
+                || cn.GetFullName().Equals(ReflectionUtilities.GetAssemblyQualifiedName(typeof(InjectorImpl))))
+                {
+                    // This would imply that we're treating injector as a singleton somewhere.  It should be copied fresh each time.
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(""), LOGGER);
+                }
+                try
+                {
+                    IClassNode new_cn = (IClassNode)injector.classHierarchy.GetNode(cn.GetFullName());
+
+                    object o = null;
+                    old.instances.TryGetValue(cn, out o);
+                    if (o != null)
+                    {
+                        injector.instances.Add(new_cn, o);
+                    }
+                }
+                catch (BindException e)
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Could not resolve name "
+                        + cn.GetFullName() + " when copying injector", e), LOGGER);
+                }
+            }
+
+            foreach (INamedParameterNode np in old.namedParameterInstances.Keys)
+            {
+                // if (!builder.namedParameters.containsKey(np)) {
+                Object o = null;
+                old.namedParameterInstances.TryGetValue(np, out o);
+                INamedParameterNode new_np = (INamedParameterNode)injector.classHierarchy.GetNode(np.GetFullName());
+                injector.namedParameterInstances.Add(new_np, o);
+            }
+
+            // Fork the aspect (if any)
+            if (old.aspect != null)
+            {
+                injector.BindAspect(old.aspect.CreateChildAspect());
+            }
+            return injector;
+        }
+
+        void BindVolatileInstanceNoCopy<T>(GenericType<T> c, T o) 
+        {
+            AssertNotConcurrent();
+            INode n = this.classHierarchy.GetNode(typeof(T));
+            if (n is IClassNode) 
+            {
+                IClassNode cn = (IClassNode) n;
+                object old = GetCachedInstance(cn);
+                if (old != null) {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new BindException("Attempt to re-bind instance.  Old value was "
+                    + old + " new value is " + o), LOGGER);
+                }
+                instances.Add(cn, o);
+            } else {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException("Expected Class but got " + c
+                    + " (probably a named parameter)."), LOGGER);
+            }
+        }
+
+        //void BindVolatileParameterNoCopy(Class<? extends Name<T>> c, T o)
+        void BindVolatileParameterNoCopy<U, T>(GenericType<U> c, T o)
+            where U : Name<T>
+        {
+            INode n = this.classHierarchy.GetNode(typeof(U));
+            if (n is INamedParameterNode) 
+            {
+                INamedParameterNode np = (INamedParameterNode) n;
+                Object old = this.configuration.GetNamedParameter(np);
+                if(old != null) 
+                {
+                    // XXX need to get the binding site here!
+                    var ex = new BindException(
+                        "Attempt to re-bind named parameter " + ReflectionUtilities.GetAssemblyQualifiedName(typeof(U)) + ".  Old value was [" + old
+                            + "] new value is [" + o + "]");
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                }
+                try 
+                {
+                    namedParameterInstances.Add(np, o);
+                } 
+                catch (ArgumentException e) 
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER); 
+                    var ex = new BindException(
+                    "Attempt to re-bind named parameter " + ReflectionUtilities.GetAssemblyQualifiedName(typeof(U)) + ".  Old value was [" + old
+                    + "] new value is [" + o + "]");
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                }
+            } 
+            else 
+            {
+                var ex = new ArgumentException("Expected Name, got " + typeof(U) + " (probably a class)");
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+            }
+        }
+
+        //public <T> void bindVolatileInstance(Class<T> c, T o) throws BindException {
+        public void BindVolatileInstance<T>(GenericType<T> iface, T inst)
+        {
+            BindVolatileInstanceNoCopy(iface, inst);
+        }
+
+        /// <summary>
+        /// Binds the volatile instance.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="inst">The inst.</param>
+        public void BindVolatileInstance<T>(T inst)
+        {
+            BindVolatileInstance<T>(GenericType<T>.Class, inst);
+        }
+
+        /// <summary>
+        /// Binds the volatile parameter.
+        /// </summary>
+        /// <typeparam name="U"></typeparam>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="iface">The iface.</param>
+        /// <param name="inst">The inst.</param>
+        public void BindVolatileParameter<U, T>(GenericType<U> iface, T inst) where U : Name<T>
+        {
+            BindVolatileParameterNoCopy(iface, inst);
+        }
+
+        /// <summary>
+        /// Binds the volatile parameter.
+        /// </summary>
+        /// <typeparam name="U"></typeparam>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="inst">The inst.</param>
+        public void BindVolatileParameter<U, T>(T inst) where U : Name<T>
+        {
+            BindVolatileParameter(GenericType<U>.Class, inst);
+        }
+
+        //public T GetNamedParameter<U, T>(GenericType<U> name) where U : Name<T>
+        //{
+        //    return (T)GetNamedInstance(typeof(U));
+        //}
+
+        //public IInjector CreateChildInjector(IConfiguration[] configurations)
+        //{
+        //    return ForkInjector(configurations);
+        //}
+        /// <summary>
+        /// Gets the injection plan for a given class name
+        /// </summary>
+        /// <param name="name">The name.</param>
+        /// <returns></returns>
+        public InjectionPlan GetInjectionPlan(string name)
+        {
+            return GetInjectionPlan(this.classHierarchy.GetNode(name));
+
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/ListInjectionPlan.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/ListInjectionPlan.cs b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/ListInjectionPlan.cs
new file mode 100644
index 0000000..8a5ad49
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/ListInjectionPlan.cs
@@ -0,0 +1,117 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System.Collections.Generic;
+using System.Text;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class ListInjectionPlan : InjectionPlan
+    {
+       private readonly IList<InjectionPlan> entries = new List<InjectionPlan>();
+       private readonly int numAlternatives;
+       private readonly bool isAmbiguous;
+       private readonly bool isInjectable;
+
+       public ListInjectionPlan(INode name, IList<InjectionPlan> entries) : base(name)
+       {
+            foreach (InjectionPlan ip in entries)
+            {
+                this.entries.Add(ip);
+            }
+            int numAlternatives = 1;
+            bool isAmbiguous = false;
+            bool isInjectable = true;
+            foreach (InjectionPlan ip in entries) 
+            {
+                numAlternatives *= ip.GetNumAlternatives();
+                isAmbiguous |= ip.IsAmbiguous();
+                isInjectable &= ip.IsInjectable();
+            }
+            this.numAlternatives = numAlternatives;
+            this.isAmbiguous = isAmbiguous;
+            this.isInjectable = isInjectable;
+       }
+
+       public override int GetNumAlternatives()
+       {
+           return numAlternatives;
+       }
+
+       public override bool IsAmbiguous()
+       {
+           return isAmbiguous;
+       }
+
+       public override bool IsInjectable()
+       {
+           return isInjectable;
+       }
+
+       public IList<InjectionPlan> GetEntryPlans()
+       {
+           return new List<InjectionPlan>(this.entries);
+       }
+
+       public override string ToAmbiguousInjectString()
+       {
+           StringBuilder sb = new StringBuilder(GetNode().GetFullName() + "(list) includes ambiguous plans [");
+           foreach (InjectionPlan ip in entries)
+           {
+               if (ip.IsAmbiguous())
+               {
+                   sb.Append("\n" + ip.ToAmbiguousInjectString());
+               }
+           }
+           sb.Append("]");
+           return sb.ToString();
+       }
+
+       public override string ToInfeasibleInjectString()
+       {
+           StringBuilder sb = new StringBuilder(GetNode().GetFullName() + "(list) includes infeasible plans [");
+           foreach (InjectionPlan ip in entries)
+           {
+               if (!ip.IsFeasible())
+               {
+                   sb.Append("\n" + ip.ToInfeasibleInjectString());
+               }
+           }
+           sb.Append("\n]");
+           return sb.ToString();
+       }
+
+       public override bool IsInfeasibleLeaf()
+       {
+           return false;
+       }
+
+       public override string ToShallowString()
+       {
+           StringBuilder sb = new StringBuilder("list { ");
+           foreach (InjectionPlan ip in entries)
+           {
+               sb.Append("\n" + ip.ToShallowString());
+           }
+           sb.Append("\n } ");
+           return null;
+       }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/SetInjectionPlan.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/SetInjectionPlan.cs b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/SetInjectionPlan.cs
new file mode 100644
index 0000000..1b530b6
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/SetInjectionPlan.cs
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System.Collections.Generic;
+using System.Text;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class SetInjectionPlan : InjectionPlan
+    {
+        private readonly ISet<InjectionPlan> entries = new MonotonicHashSet<InjectionPlan>();
+        private readonly int numAlternatives;
+        private readonly bool isAmbiguous;
+        private readonly bool isInjectable;
+
+       public SetInjectionPlan(INode name, ISet<InjectionPlan> entries) : base(name)
+       {
+            foreach (InjectionPlan ip in entries)
+            {
+                this.entries.Add(ip);
+            }
+            int numAlternatives = 1;
+            bool isAmbiguous = false;
+            bool isInjectable = true;
+            foreach (InjectionPlan ip in entries) 
+            {
+                numAlternatives *= ip.GetNumAlternatives();
+                isAmbiguous |= ip.IsAmbiguous();
+                isInjectable &= ip.IsInjectable();
+            }
+            this.numAlternatives = numAlternatives;
+            this.isAmbiguous = isAmbiguous;
+            this.isInjectable = isInjectable;
+        }
+
+       public override int GetNumAlternatives()
+       {
+           return numAlternatives;
+       }
+
+       public override bool IsAmbiguous()
+       {
+           return isAmbiguous;
+       }
+
+       public override bool IsInjectable()
+       {
+           return isInjectable;
+       }
+
+       //public override bool HasFutureDependency()
+       //{
+       //    return false;
+       //}
+
+       public ISet<InjectionPlan> GetEntryPlans()
+       {
+           return new MonotonicHashSet<InjectionPlan>(this.entries);
+       }
+
+       public override string ToAmbiguousInjectString() 
+        {
+            StringBuilder sb = new StringBuilder(GetNode().GetFullName() + "(set) includes ambiguous plans [");
+            foreach (InjectionPlan ip in entries) 
+            {
+                if(ip.IsAmbiguous()) 
+                {
+                    sb.Append("\n" + ip.ToAmbiguousInjectString());
+                }
+            }
+            sb.Append("]");
+            return sb.ToString();
+        }
+
+        public override string ToInfeasibleInjectString() 
+        {
+            StringBuilder sb = new StringBuilder(GetNode().GetFullName() + "(set) includes infeasible plans [");
+            foreach (InjectionPlan ip in entries) 
+            {
+                if(!ip.IsFeasible()) 
+                {
+                    sb.Append("\n" + ip.ToInfeasibleInjectString());
+                }
+            }
+            sb.Append("\n]");
+            return sb.ToString();
+        }
+
+        public override bool IsInfeasibleLeaf()
+        {
+            return false;
+        }
+
+        public override string ToShallowString() 
+        {
+            StringBuilder sb = new StringBuilder("set { ");
+            foreach (InjectionPlan ip in entries) 
+            {
+                sb.Append("\n" + ip.ToShallowString());
+            }
+            sb.Append("\n } ");
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/Subplan.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/Subplan.cs b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/Subplan.cs
new file mode 100644
index 0000000..b0b0229
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/Subplan.cs
@@ -0,0 +1,235 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class Subplan : InjectionPlan
+    {
+        private static readonly Logger LOGGER = Logger.GetLogger(typeof(Subplan));
+
+        InjectionPlan[] alternatives; //all implementatios on the same interface
+        int numAlternatives;
+        int selectedIndex; //the implementation that is bound
+
+        public Subplan(INode n, int selectedIndex, InjectionPlan[] alternatives)
+            : base(n)
+        {
+            this.alternatives = alternatives;
+            if (selectedIndex < -1 || selectedIndex >= alternatives.Length)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IndexOutOfRangeException(), LOGGER);
+            }
+            this.selectedIndex = selectedIndex;
+            if (selectedIndex != -1)   //one was bound
+            {
+                this.numAlternatives = alternatives[selectedIndex].GetNumAlternatives();
+            }
+            else // no one was bound, but anyone could be used
+            {
+                int numAlternatives = 0;
+                foreach (InjectionPlan a in alternatives)
+                {
+                    numAlternatives += a.GetNumAlternatives();
+                }
+                this.numAlternatives = numAlternatives;
+            }
+        }
+
+        public new ICollection<InjectionPlan> GetChildren() 
+        {
+            return new ReadOnlyCollection<InjectionPlan>(this.alternatives.OfType<InjectionPlan>().ToList());
+        }
+
+        public Subplan(INode n, InjectionPlan[] alternatives)
+            : this(n, -1, alternatives)
+        {           
+        }
+
+        public override int GetNumAlternatives()
+        {
+            return this.numAlternatives;
+        }
+
+        public override bool IsAmbiguous()
+        {
+            if (selectedIndex == -1)
+            {
+                return true;
+            }
+            return alternatives[selectedIndex].IsAmbiguous();
+        }
+
+        public override bool IsInjectable()
+        {
+            if (selectedIndex == -1)
+            {
+                return false;
+            }
+            else
+            {
+                return alternatives[selectedIndex].IsInjectable();
+            }
+        }
+
+        public override string ToString()
+        {
+            if (alternatives.Length == 1)
+            {
+                return GetNode().GetName() + " = " + alternatives[0];
+            }
+            else if (alternatives.Length == 0)
+            {
+                return GetNode().GetName() + ": no injectable constructors";
+            }
+            StringBuilder sb = new StringBuilder("[");
+            sb.Append(GetNode().GetName() + " = " + alternatives[0]);
+            for (int i = 1; i < alternatives.Length; i++)
+            {
+                sb.Append(" | " + alternatives[i]);
+            }
+            sb.Append("]");
+            return sb.ToString();
+        }
+
+        public override string ToShallowString()
+        {
+            if (alternatives.Length == 1)
+            {
+                return GetNode().GetName() + " = " + alternatives[0].ToShallowString();
+            }
+            else if (alternatives.Length == 0)
+            {
+                return GetNode().GetName() + ": no injectable constructors";
+            }
+            StringBuilder sb = new StringBuilder("[");
+            sb.Append(GetNode().GetName() + " = " + alternatives[0].ToShallowString());
+            for (int i = 1; i < alternatives.Length; i++)
+            {
+                sb.Append(" | " + alternatives[i].ToShallowString());
+            }
+            sb.Append("]");
+            return sb.ToString();
+        }
+
+        public int GetSelectedIndex()
+        {
+            return selectedIndex;
+        }
+
+        public InjectionPlan GetDelegatedPlan() 
+        {
+            if (selectedIndex != -1) 
+            {
+                return alternatives[selectedIndex];
+            }
+            Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Error in getting GetDelegatedPlan."), LOGGER);
+            return null;
+        }
+
+        //public override bool HasFutureDependency()
+        //{
+        //    if (selectedIndex == -1)
+        //    {
+        //        throw new IllegalStateException("hasFutureDependency() called on ambiguous subplan!");
+        //    }
+        //    return alternatives[selectedIndex].HasFutureDependency();
+        //}
+
+        public override string ToAmbiguousInjectString()
+        {
+            if (alternatives.Length == 1) 
+            {
+                return alternatives[0].ToAmbiguousInjectString();
+            } 
+            else if (selectedIndex != -1) 
+            {
+                return alternatives[selectedIndex].ToAmbiguousInjectString();
+            } 
+            else 
+            {
+                IList<InjectionPlan> alts = new List<InjectionPlan>();
+                IList<InjectionPlan> ambig = new List<InjectionPlan>();
+                foreach (InjectionPlan alt in alternatives) 
+                {
+                    if (alt.IsFeasible()) 
+                    {
+                        alts.Add(alt);
+                    }
+                    if (alt.IsAmbiguous()) 
+                    {
+                        ambig.Add(alt);
+                    }
+                }
+                StringBuilder sb = new StringBuilder("Ambiguous subplan " + GetNode().GetFullName());
+                foreach (InjectionPlan alt in alts) 
+                {
+                    sb.Append("\n  " + alt.ToShallowString() + " ");
+                }
+                foreach (InjectionPlan alt in ambig) 
+                {
+                    sb.Append("\n  " + alt.ToShallowString() + " ");
+                }
+                sb.Append("\n]");
+                return sb.ToString();
+            }
+        }
+
+        public override string ToInfeasibleInjectString()
+        {
+            if (alternatives.Length == 1) 
+            {
+                return alternatives[0].ToInfeasibleInjectString();
+            }
+            else if (alternatives.Length == 0)
+            {
+                return "No known implementations / injectable constructors for "
+                + this.GetNode().GetFullName();
+            } 
+            else if (selectedIndex != -1) 
+            {
+                return alternatives[selectedIndex].ToInfeasibleInjectString();
+            } 
+            else 
+            {
+                return "Multiple infeasible plans: " + ToPrettyString();
+            }
+        }
+
+        public InjectionPlan[] GetPlans() 
+        {
+            InjectionPlan[] copy = new InjectionPlan[alternatives.Length];
+            Array.Copy(alternatives, copy, alternatives.Length); // not sure if it does deep copy??
+            return copy;
+        }
+
+        public override bool IsInfeasibleLeaf()
+        {
+            return false;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/Tang/TangFactory.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/Tang/TangFactory.cs b/lang/cs/Source/TANG/Tang/Implementations/Tang/TangFactory.cs
new file mode 100644
index 0000000..c54f562
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/Tang/TangFactory.cs
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using Org.Apache.Reef.Tang.Interface;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class TangFactory
+    {
+        public static ITang GetTang()
+        {
+            return new TangImpl();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/Tang/TangImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/Tang/TangImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/Tang/TangImpl.cs
new file mode 100644
index 0000000..5e0181b
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/Tang/TangImpl.cs
@@ -0,0 +1,201 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Formats;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class TangImpl : ITang
+    {
+        private static readonly Logger LOGGER = Logger.GetLogger(typeof(TangImpl));
+
+        private static IDictionary<SetValuedKey, ICsClassHierarchy> defaultClassHierarchy = new Dictionary<SetValuedKey, ICsClassHierarchy>();
+
+        public IInjector NewInjector()
+        {
+            try
+            {
+                return NewInjector(new ConfigurationImpl[] {});
+            }
+            catch (BindException e)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Unexpected error from empty configuration", e), LOGGER);
+                return null;
+            }
+        }
+
+        public IInjector NewInjector(string[] assemblies, string configurationFileName)
+        {
+            ITang tang = TangFactory.GetTang();
+            ICsConfigurationBuilder cb1 = tang.NewConfigurationBuilder(assemblies);
+            ConfigurationFile.AddConfigurationFromFile(cb1, configurationFileName);
+            IConfiguration conf = cb1.Build();
+
+            IInjector injector = tang.NewInjector(conf);
+            return injector;
+        }
+
+        public ICsConfigurationBuilder NewConfigurationBuilder(IConfiguration conf)
+        {
+            return NewConfigurationBuilder(new IConfiguration[] { conf });
+        }
+
+        //public IInjector NewInjector(string[] assemblies, IDictionary<string, string> configurations)
+        //{
+        //    ITang tang = TangFactory.GetTang();
+        //    ICsConfigurationBuilder cb1 = tang.NewConfigurationBuilder(assemblies);
+        //    ConfigurationFile.ProcessConfigData(cb1, configurations);
+        //    IConfiguration conf = cb1.Build();
+
+        //    IInjector injector = tang.NewInjector(conf);
+        //    return injector;
+        //}
+
+        public IInjector NewInjector(string[] assemblies, IDictionary<string, string> configurations)
+        {
+            IList<KeyValuePair<string, string>> conf = new List<KeyValuePair<string, string>>();
+            foreach (KeyValuePair<string, string> kp in configurations)
+            {
+                conf.Add(kp);
+            }
+            return NewInjector(assemblies, conf);
+        }
+
+        public IInjector NewInjector(string[] assemblies, IList<KeyValuePair<string, string>> configurations)
+        {
+            ITang tang = TangFactory.GetTang();
+            ICsConfigurationBuilder cb1 = tang.NewConfigurationBuilder(assemblies);
+            ConfigurationFile.ProcessConfigData(cb1, configurations);
+            IConfiguration conf = cb1.Build();
+
+            IInjector injector = tang.NewInjector(conf);
+            return injector;
+        }
+
+        public IInjector NewInjector(IConfiguration[] confs)
+        {
+            return new InjectorImpl(new CsConfigurationBuilderImpl(confs).Build());
+        }
+
+        public IInjector NewInjector(IConfiguration conf)
+        {
+            //return new InjectorImpl(conf);
+            try
+            {
+                return NewInjector(new ConfigurationImpl[] { (ConfigurationImpl)conf });
+            }
+            catch (BindException e)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Unexpected error cloning configuration", e), LOGGER);
+                return null; 
+            }
+        }
+
+        public IClassHierarchy GetClassHierarchy(string[] assemblies)
+        {
+            return GetDefaultClassHierarchy(assemblies, new Type[] { });
+        }
+
+        public ICsClassHierarchy GetDefaultClassHierarchy()
+        {
+            return GetDefaultClassHierarchy(new string[0], new Type[0]);
+        }
+
+        public ICsClassHierarchy GetDefaultClassHierarchy(string[] assemblies, Type[] parameterParsers)
+        {
+            SetValuedKey key = new SetValuedKey(assemblies, parameterParsers);
+
+            ICsClassHierarchy ret = null;
+            defaultClassHierarchy.TryGetValue(key, out ret);
+            if (ret == null)
+            {
+                ret = new ClassHierarchyImpl(assemblies, parameterParsers);
+                defaultClassHierarchy.Add(key, ret);
+            }
+            return ret;
+        }
+
+        public ICsConfigurationBuilder NewConfigurationBuilder()
+        {
+            try 
+            {
+                return NewConfigurationBuilder(new string[0], new IConfiguration[0], new Type[0]);
+            } 
+            catch (BindException e) 
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(
+                    "Caught unexpeceted bind exception!  Implementation bug.", e), LOGGER);
+                return null;
+            }
+        }
+
+        public ICsConfigurationBuilder NewConfigurationBuilder(string[] assemblies)
+        {
+            try
+            {
+                return NewConfigurationBuilder(assemblies, new IConfiguration[0], new Type[0]);
+            }
+            catch (BindException e)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(
+                    "Caught unexpeceted bind exception!  Implementation bug.", e), LOGGER);
+                return null;
+            }
+        }
+
+        public IConfigurationBuilder NewConfigurationBuilder(IClassHierarchy classHierarchy)
+        {
+            return new ConfigurationBuilderImpl(classHierarchy);
+        }
+
+        public ICsConfigurationBuilder NewConfigurationBuilder(ICsClassHierarchy classHierarchy)
+        {
+            return new CsConfigurationBuilderImpl(classHierarchy);
+        }
+
+        public ICsConfigurationBuilder NewConfigurationBuilder(IConfiguration[] confs)
+        {
+            return NewConfigurationBuilder(new string[0], confs, new Type[0]);
+        }
+
+        public ICsConfigurationBuilder NewConfigurationBuilder(string[] assemblies, IConfiguration[] confs, Type[] parameterParsers)
+        {
+            return new CsConfigurationBuilderImpl(assemblies, confs, parameterParsers);
+        }
+
+        public ICsConfigurationBuilder NewConfigurationBuilder(Type[] parameterParsers) 
+        {
+            return NewConfigurationBuilder(new string[0], new IConfiguration[0], parameterParsers);
+        }
+
+        public static void Reset() 
+        {
+            defaultClassHierarchy = new Dictionary<SetValuedKey, ICsClassHierarchy>(); 
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Interface/IAspect.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Interface/IAspect.cs b/lang/cs/Source/TANG/Tang/Interface/IAspect.cs
new file mode 100644
index 0000000..2c19897
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Interface/IAspect.cs
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System.Reflection;
+using Org.Apache.Reef.Tang.Implementations;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Interface
+{
+    public interface Aspect
+    {
+        object Inject(IConstructorDef def, ConstructorInfo constructor, object[] args);
+        void InjectionFutureInstantiated<T>(IInjectionFuture<T> f, object t);
+        Aspect CreateChildAspect();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Interface/IClassHierarchy.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Interface/IClassHierarchy.cs b/lang/cs/Source/TANG/Tang/Interface/IClassHierarchy.cs
new file mode 100644
index 0000000..7428942
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Interface/IClassHierarchy.cs
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Interface
+{
+    public interface IClassHierarchy
+    {
+        INode GetNode(string fullName);
+        INode GetNamespace();
+        bool IsImplementation(IClassNode inter, IClassNode impl);
+        IClassHierarchy Merge(IClassHierarchy ch);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Interface/IConfiguration.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Interface/IConfiguration.cs b/lang/cs/Source/TANG/Tang/Interface/IConfiguration.cs
new file mode 100644
index 0000000..6903d19
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Interface/IConfiguration.cs
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Interface
+{
+    public interface IConfiguration
+    {
+        IConfigurationBuilder newBuilder();
+        string GetNamedParameter(INamedParameterNode np);
+        IClassHierarchy GetClassHierarchy();
+
+        ISet<Object> GetBoundSet(INamedParameterNode np); //named parameter for a set
+        IList<Object> GetBoundList(INamedParameterNode np); //named parameter for a list
+
+        IClassNode GetBoundConstructor(IClassNode cn);
+        IClassNode GetBoundImplementation(IClassNode cn);
+        IConstructorDef GetLegacyConstructor(IClassNode cn);
+
+        ICollection<IClassNode> GetBoundImplementations();
+        ICollection<IClassNode> GetBoundConstructors();
+        ICollection<INamedParameterNode> GetNamedParameters();
+        ICollection<IClassNode> GetLegacyConstructors();
+
+        IEnumerator<KeyValuePair<INamedParameterNode, object>> GetBoundSets();
+        IDictionary<INamedParameterNode, IList<object>> GetBoundList();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Interface/IConfigurationBuilder.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Interface/IConfigurationBuilder.cs b/lang/cs/Source/TANG/Tang/Interface/IConfigurationBuilder.cs
new file mode 100644
index 0000000..640b11d
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Interface/IConfigurationBuilder.cs
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Interface
+{
+    public interface IConfigurationBuilder
+    {
+        void AddConfiguration(IConfiguration c); 
+        IClassHierarchy GetClassHierarchy();
+        IConfiguration Build();
+        void Bind(string iface, string impl);
+        void Bind(INode key, INode value);
+
+        void BindConstructor(IClassNode k, IClassNode v); //v extended from ExternalConstructor
+        string ClassPrettyDefaultString(string longName);
+        string ClassPrettyDescriptionString(string longName);
+
+        void RegisterLegacyConstructor(IClassNode cn, IList<IClassNode> args);
+        void RegisterLegacyConstructor(string cn, IList<string> args);
+        void RegisterLegacyConstructor(IClassNode c, IList<IConstructorArg> args);
+
+        void BindSetEntry(string iface, string impl);
+        void BindSetEntry(string iface, INode impl);
+        void BindSetEntry(INamedParameterNode iface, string impl);
+        void BindSetEntry(INamedParameterNode iface, INode impl);
+
+        void BindList(string iface, IList<string> impl);
+        void BindList(string iface, IList<INode> impl);
+        void BindList(INamedParameterNode iface, IList<INode> impl);
+        void BindList(INamedParameterNode iface, IList<string> impl);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Interface/ICsClassHierarchy.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Interface/ICsClassHierarchy.cs b/lang/cs/Source/TANG/Tang/Interface/ICsClassHierarchy.cs
new file mode 100644
index 0000000..07c94dc
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Interface/ICsClassHierarchy.cs
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Interface
+{
+    public interface ICsClassHierarchy : IClassHierarchy
+    {
+        INode GetNode(Type c);
+        Type ClassForName(string name);
+        object Parse(INamedParameterNode name, string value);
+        object ParseDefaultValue(INamedParameterNode name);
+
+
+    }
+}