Beispiel #1
0
        public ValidGraphPath[] generateValidPaths(int graphValidPathCount) {


            // initialize valid graph paths
            ValidGraphPath[] validPaths = new ValidGraphPath[graphValidPathCount];
            for (int graphIdx = 0; graphIdx < graphValidPathCount; graphIdx++) {
                validPaths[graphIdx] = new ValidGraphPath(this.graphDepth);
            }

            List<ITypeReference> allInterfacesList = this.graphInterfaces.Keys.OfType<ITypeReference>().ToList<ITypeReference>();
            PossibleNode[] currentRoundBasePossibleNodes = new PossibleNode[graphValidPathCount];


            // generate valid paths
            for (int idx = 0; idx < this.graphDepth; idx++) {

                // initialize path element
                for (int validPathIdx = 0; validPathIdx < graphValidPathCount; validPathIdx++) {
                    validPaths[validPathIdx].pathElements[idx] = new PathElement();
                    validPaths[validPathIdx].pathElements[idx].validPathId = validPathIdx;

                    if (idx != 0) {
                        validPaths[validPathIdx].pathIndices[idx] = this.prng.Next(this.graphDimension);
                    }
                    else {
                        // mark path index of start node as -1
                        validPaths[validPathIdx].pathIndices[0] = -1;
                    }
                }


                // check if it is the first element of the valid path
                // => always the root for each valid path
                if (idx == 0) {


                    // get random base class that is used to generate the valid path element (use it for all first elements of the valid paths)
                    ITypeReference baseInterface = allInterfacesList.ElementAt(this.prng.Next(allInterfacesList.Count()));
                    List<PossibleNode> baseList = (List<PossibleNode>)this.graphInterfaces[baseInterface];
                    PossibleNode basePossibleNode = baseList.ElementAt(this.prng.Next(baseList.Count()));


                    // for each valid path add a path element
                    for (int validPathIdx = 0; validPathIdx < graphValidPathCount; validPathIdx++) {

                        // get valid interface
                        ITypeReference firstInterface = basePossibleNode.givenClass.Interfaces.ElementAt(this.prng.Next(basePossibleNode.givenClass.Interfaces.Count()));
                        validPaths[validPathIdx].pathElements[idx].validInterfaces.Add(firstInterface);

                        // add interface to mandatory list (if it is not already in it)
                        if (!validPaths[0].pathElements[idx].mandatoryInterfaces.Contains(firstInterface)) {
                            validPaths[0].pathElements[idx].mandatoryInterfaces.Add(firstInterface);
                        }


                        // add valid interfaces to the path element
                        bool addAnotherInterface = true;
                        int addInterfaceWeight = 3;
                        while (addAnotherInterface) {

                            // decide wether to add another valid interface or not
                            switch (this.prng.Next(addInterfaceWeight)) {

                                // add another interface to the list of valid interfaces
                                case 0:
                                case 1: {

                                        // check if there exists more interfaces that could be added to the list of valid interfaces
                                        if (basePossibleNode.givenClass.Interfaces.Count() == validPaths[validPathIdx].pathElements[idx].validInterfaces.Count()) {
                                            addAnotherInterface = false;
                                            break;
                                        }

                                        // add a random interface that is implemented by the base possible node
                                        int nextInterfaceIdx = this.prng.Next(basePossibleNode.givenClass.Interfaces.Count());
                                        while (true) {
                                            ITypeReference tempInterface = basePossibleNode.givenClass.Interfaces.ElementAt(nextInterfaceIdx);

                                            // check if chosen interface is already added to the list of valid interfaces
                                            // => try next interface implemented by the base possible node
                                            if (validPaths[validPathIdx].pathElements[idx].validInterfaces.Contains(tempInterface)) {
                                                nextInterfaceIdx = (nextInterfaceIdx + 1) % basePossibleNode.givenClass.Interfaces.Count();
                                            }

                                            // => add interface to list of valid interfaces
                                            else {
                                                validPaths[validPathIdx].pathElements[idx].validInterfaces.Add(tempInterface);

                                                // add interface to mandatory list (if it is not already in it)
                                                if (!validPaths[0].pathElements[idx].mandatoryInterfaces.Contains(tempInterface)) {
                                                    validPaths[0].pathElements[idx].mandatoryInterfaces.Add(tempInterface);
                                                }
                                                break;
                                            }
                                        }

                                        break;
                                    }

                                //do not add any more interfaces
                                default: {
                                        addAnotherInterface = false;

                                        break;
                                    }
                            }

                            // make adding another invalid interface more unlikely
                            addInterfaceWeight++;

                        }


                        // add invalid interfaces to the path element
                        addAnotherInterface = true;
                        addInterfaceWeight = 2;
                        while (addAnotherInterface) {

                            // decide wether to add another valid interface or not
                            switch (this.prng.Next(addInterfaceWeight)) {

                                // add another interface to the list of invalid interfaces
                                case 0:
                                case 1: {

                                        // check if there exists anymore interfaces that could be added to the list of invalid interfaces
                                        if (allInterfacesList.Count() <= (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + validPaths[validPathIdx].pathElements[idx].validInterfaces.Count())) {
                                            if (allInterfacesList.Count() == (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + validPaths[validPathIdx].pathElements[idx].validInterfaces.Count())) {
                                                addAnotherInterface = false;
                                                break;
                                            }

                                            throw new ArgumentException("The sum of valid and invalid interfaces should never be greater than the count of all interfaces.");
                                        }

                                        // check if there exists anymore interfaces that could be added to the list of invalid interfaces
                                        if (allInterfacesList.Count() <= (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + basePossibleNode.givenClass.Interfaces.Count())) {
                                            if (allInterfacesList.Count() == (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + basePossibleNode.givenClass.Interfaces.Count())) {
                                                addAnotherInterface = false;
                                                break;
                                            }

                                            throw new ArgumentException("The sum of implemented and invalid interfaces should never be greater than the count of all interfaces.");
                                        }

                                        // add a random interface that is NOT implemented by the base possible node
                                        int nextInterfaceIdx = this.prng.Next(allInterfacesList.Count());
                                        while (true) {
                                            ITypeReference tempInterface = allInterfacesList.ElementAt(nextInterfaceIdx);

                                            // check if chosen interface is NOT added to the list of invalid interfaces
                                            // and NOT implemented by the base possible node
                                            // => if it is try next interface of all interfaces
                                            if (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Contains(tempInterface)
                                                || basePossibleNode.givenClass.Interfaces.Contains(tempInterface)) {

                                                nextInterfaceIdx = (nextInterfaceIdx + 1) % allInterfacesList.Count();
                                            }

                                            // => add interface to list of invalid interfaces
                                            else {
                                                
                                                validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Add(tempInterface);

                                                // add interface to forbidden list (if it is not already in it)
                                                if (!validPaths[0].pathElements[idx].forbiddenInterfaces.Contains(tempInterface)) {
                                                    validPaths[0].pathElements[idx].forbiddenInterfaces.Add(tempInterface);
                                                }

                                                break;
                                            }
                                        }

                                        break;
                                    }

                                //do not add any more interfaces
                                default: {
                                        addAnotherInterface = false;

                                        break;
                                    }
                            }

                            // make adding another invalid interface more unlikely
                            addInterfaceWeight++;

                        }
                    }
                }


                // => not the first element of the valid paths
                else {

                    // for each valid path add a path element
                    for (int validPathIdx = 0; validPathIdx < graphValidPathCount; validPathIdx++) {

                        // if the valid path id is not the first
                        // => search through all already chosen valid paths if the current path is the same until now
                        // and get the idx of this valid path (the first occurring is all that is needed)
                        int samePathIdx = -1;
                        if (validPathIdx != 0) {
                            for(int tempPathIdx = 0; tempPathIdx < validPathIdx; tempPathIdx++) {
                                bool samePath = true;
                                for(int depth = 0; depth <= idx; depth++) {
                                    if(validPaths[tempPathIdx].pathIndices[depth] != validPaths[validPathIdx].pathIndices[depth]) {
                                        samePath = false;
                                        break;
                                    }
                                }
                                if(samePath) {
                                    samePathIdx = tempPathIdx;
                                    break;
                                }
                            }
                        }


                        // if there does not exist a path that is the same up to this point
                        // => chose a random base possible node
                        PossibleNode basePossibleNode;
                        if (samePathIdx == -1) {

                            // get random base class that is used to generate the valid path element
                            ITypeReference baseInterface = allInterfacesList.ElementAt(this.prng.Next(allInterfacesList.Count()));
                            validPaths[validPathIdx].pathElements[idx].validInterfaces.Add(baseInterface);
                            List<PossibleNode> baseList = (List<PossibleNode>)this.graphInterfaces[baseInterface];
                            basePossibleNode = baseList.ElementAt(this.prng.Next(baseList.Count()));

                            // add interface to mandatory list (if it is not already in it)
                            if (!validPaths[validPathIdx].pathElements[idx].mandatoryInterfaces.Contains(baseInterface)) {
                                validPaths[validPathIdx].pathElements[idx].mandatoryInterfaces.Add(baseInterface);
                            }
                        }

                        // if there already exists a path
                        // => use the same base possible node
                        else {

                            basePossibleNode = currentRoundBasePossibleNodes[samePathIdx];

                            ITypeReference baseInterface = basePossibleNode.givenClass.Interfaces.ElementAt(this.prng.Next(basePossibleNode.givenClass.Interfaces.Count()));
                            validPaths[validPathIdx].pathElements[idx].validInterfaces.Add(baseInterface);

                            // add interface to mandatory list (if it is not already in it)
                            if (!validPaths[samePathIdx].pathElements[idx].mandatoryInterfaces.Contains(baseInterface)) {
                                validPaths[samePathIdx].pathElements[idx].mandatoryInterfaces.Add(baseInterface);
                            }

                        }


                        // add valid interfaces to the path element
                        bool addAnotherInterface = true;
                        int addInterfaceWeight = 3;
                        while (addAnotherInterface) {

                            // decide wether to add another valid interface or not
                            switch (this.prng.Next(addInterfaceWeight)) {

                                // add another interface to the list of valid interfaces
                                case 0:
                                case 1: {

                                        // check if there exists more interfaces that could be added to the list of valid interfaces
                                        if (basePossibleNode.givenClass.Interfaces.Count() == validPaths[validPathIdx].pathElements[idx].validInterfaces.Count()) {
                                            addAnotherInterface = false;
                                            break;
                                        }

                                        // add a random interface that is implemented by the base possible node
                                        int nextInterfaceIdx = this.prng.Next(basePossibleNode.givenClass.Interfaces.Count());
                                        while (true) {
                                            ITypeReference tempInterface = basePossibleNode.givenClass.Interfaces.ElementAt(nextInterfaceIdx);

                                            // check if chosen interface is already added to the list of valid interfaces
                                            // => try next interface implemented by the base possible node
                                            if (validPaths[validPathIdx].pathElements[idx].validInterfaces.Contains(tempInterface)) {
                                                nextInterfaceIdx = (nextInterfaceIdx + 1) % basePossibleNode.givenClass.Interfaces.Count();
                                            }

                                            // => add interface to list of valid interfaces
                                            else {
                                                validPaths[validPathIdx].pathElements[idx].validInterfaces.Add(tempInterface);

                                                // check if there exist a prior path that has an element at the same position
                                                // => if not, add interface to list of mandatory interfaces of this path
                                                if (samePathIdx == -1) {
                                                    if (!validPaths[validPathIdx].pathElements[idx].mandatoryInterfaces.Contains(tempInterface)) {
                                                        validPaths[validPathIdx].pathElements[idx].mandatoryInterfaces.Add(tempInterface);
                                                    }
                                                }

                                                // => if there is, add interface to list of mandatory interfaces of the prior path
                                                else {
                                                    if (!validPaths[samePathIdx].pathElements[idx].mandatoryInterfaces.Contains(tempInterface)) {
                                                        validPaths[samePathIdx].pathElements[idx].mandatoryInterfaces.Add(tempInterface);
                                                    }
                                                }

                                                break;
                                            }
                                        }

                                        break;
                                    }

                                //do not add any more interfaces
                                default: {
                                        addAnotherInterface = false;

                                        break;
                                    }
                            }

                            // make adding another invalid interface more unlikely
                            addInterfaceWeight++;

                        }


                        // add invalid interfaces to the path element
                        addAnotherInterface = true;
                        addInterfaceWeight = 2;
                        while (addAnotherInterface) {

                            // decide wether to add another valid interface or not
                            switch (this.prng.Next(addInterfaceWeight)) {

                                // add another interface to the list of invalid interfaces
                                case 0:
                                case 1: {

                                        // check if there exists anymore interfaces that could be added to the list of invalid interfaces
                                        if (allInterfacesList.Count() <= (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + validPaths[validPathIdx].pathElements[idx].validInterfaces.Count())) {
                                            if (allInterfacesList.Count() == (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + validPaths[validPathIdx].pathElements[idx].validInterfaces.Count())) {
                                                addAnotherInterface = false;
                                                break;
                                            }

                                            throw new ArgumentException("The sum of valid and invalid interfaces should never be greater than the count of all interfaces.");
                                        }

                                        // check if there exists anymore interfaces that could be added to the list of invalid interfaces 
                                        if (allInterfacesList.Count() <= (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + basePossibleNode.givenClass.Interfaces.Count())) {
                                            if (allInterfacesList.Count() == (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + basePossibleNode.givenClass.Interfaces.Count())) {
                                                addAnotherInterface = false;
                                                break;
                                            }

                                            throw new ArgumentException("The sum of implemented and invalid interfaces should never be greater than the count of all interfaces.");
                                        }


                                        // add a random interface that is NOT implemented by the base possible node
                                        int nextInterfaceIdx = this.prng.Next(allInterfacesList.Count());
                                        while (true) {
                                            ITypeReference tempInterface = allInterfacesList.ElementAt(nextInterfaceIdx);

                                            // check if chosen interface is NOT added to the list of invalid interfaces
                                            // and NOT implemented by the base possible node
                                            // => if it is try next interface of all interfaces
                                            if (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Contains(tempInterface)
                                                || basePossibleNode.givenClass.Interfaces.Contains(tempInterface)) {

                                                nextInterfaceIdx = (nextInterfaceIdx + 1) % allInterfacesList.Count();
                                            }

                                            // => add interface to list of invalid interfaces
                                            else {
                                                validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Add(tempInterface);

                                                // check if there exist a prior path that has an element at the same position
                                                // => if not, add interface to list of forbidden interfaces of this path
                                                if (samePathIdx == -1) {
                                                    if (!validPaths[validPathIdx].pathElements[idx].forbiddenInterfaces.Contains(tempInterface)) {
                                                        validPaths[validPathIdx].pathElements[idx].forbiddenInterfaces.Add(tempInterface);
                                                    }
                                                }

                                                // => if there is, add interface to list of forbidden interfaces of the prior path
                                                else {
                                                    if (!validPaths[samePathIdx].pathElements[idx].forbiddenInterfaces.Contains(tempInterface)) {
                                                        validPaths[samePathIdx].pathElements[idx].forbiddenInterfaces.Add(tempInterface);
                                                    }
                                                }

                                                break;
                                            }
                                        }

                                        break;
                                    }

                                //do not add any more interfaces
                                default: {
                                        addAnotherInterface = false;

                                        break;
                                    }
                            }

                            // make adding another invalid interface more unlikely
                            addInterfaceWeight++;

                        }

                        // add current base possible node to the current round base possible nodes
                        currentRoundBasePossibleNodes[validPathIdx] = basePossibleNode;

                    }
                }
            }


            // set all mandatory and forbidden interfaces lists of all nodes that lie on the same path
            for (int idx = 0; idx < this.graphDepth; idx++) {

                for (int validPathIdx = 1; validPathIdx < graphValidPathCount; validPathIdx++) {

                    // search through all prior valid paths if the current path is the same until now
                    // and get the idx of this valid path (the first occurring is all that is needed)
                    int samePathIdx = -1;

                    for (int tempPathIdx = 0; tempPathIdx < validPathIdx; tempPathIdx++) {
                        bool samePath = true;
                        for (int depth = 0; depth <= idx; depth++) {
                            if (validPaths[tempPathIdx].pathIndices[depth] != validPaths[validPathIdx].pathIndices[depth]) {
                                samePath = false;
                                break;
                            }
                        }
                        if (samePath) {
                            samePathIdx = tempPathIdx;
                            break;
                        }
                    }

                    // if a path was found which is the same up to the current point
                    // => set the mandatory and forbidden list to the lists of the found path
                    if (samePathIdx != -1) {
                        validPaths[validPathIdx].pathElements[idx].mandatoryInterfaces = validPaths[samePathIdx].pathElements[idx].mandatoryInterfaces;
                        validPaths[validPathIdx].pathElements[idx].forbiddenInterfaces = validPaths[samePathIdx].pathElements[idx].forbiddenInterfaces;
                    }
                }
            }
            

            return validPaths;

        }
        // this function adds the created iNode interface to the class and also implements all neded functions
        public void addNodeInterfaceToTargetClass(NamespaceTypeDefinition givenClass) {

            this.logger.writeLine("");
            this.logger.writeLine("Add node interface \"" + this.nodeInterface.ToString() + "\" to class \"" + givenClass.ToString() + "\"");

            // check if generated interface was already added to target class
            if (givenClass.Interfaces != null
                && givenClass.Interfaces.Contains(this.nodeInterface)) {
                this.logger.writeLine("Class \"" + givenClass.ToString() + "\" already contains node interface \"" + this.nodeInterface.ToString() + "\"");
                return;
            }

            // add nodes interface to class
            if (givenClass.Interfaces != null) {
                givenClass.Interfaces.Add(this.nodeInterface);
            }
            else {
                givenClass.Interfaces = new List<ITypeReference>();
                givenClass.Interfaces.Add(this.nodeInterface);
            }

            // add start pointer field
            FieldDefinition startPointerField = new FieldDefinition();
            startPointerField.IsCompileTimeConstant = false;
            startPointerField.IsNotSerialized = false;
            startPointerField.IsReadOnly = false;
            startPointerField.IsRuntimeSpecial = false;
            startPointerField.IsSpecialName = false;
            startPointerField.Type = this.nodeInterface;
            startPointerField.IsStatic = false;
            startPointerField.Visibility = TypeMemberVisibility.Public;
            startPointerField.Name = host.NameTable.GetNameFor("startPointer");
            startPointerField.InternFactory = host.InternFactory;
            startPointerField.ContainingTypeDefinition = givenClass;
            if (givenClass.Fields != null) {
                givenClass.Fields.Add(startPointerField);
            }
            else {
                givenClass.Fields = new List<IFieldDefinition>();
                givenClass.Fields.Add(startPointerField);
            }

            // create getter for the startPointer variable
            MethodDefinition startPointerGetMethod = this.helperClass.createNewMethod("startPointer_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ILGenerator ilGenerator = new ILGenerator(host, startPointerGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, startPointerField);
            ilGenerator.Emit(OperationCode.Ret);
            IMethodBody body = new ILGeneratorMethodBody(ilGenerator, true, 1, startPointerGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            startPointerGetMethod.Body = body;

            // create setter for the startPointer variable
            List<IParameterDefinition> parameters = new List<IParameterDefinition>();
            ParameterDefinition parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Name = host.NameTable.GetNameFor("value");
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            MethodDefinition startPointerSetMethod = this.helperClass.createNewMethod("startPointer_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, startPointerSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stfld, startPointerField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, startPointerSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            startPointerSetMethod.Body = body;

            // add childNodes array field
            FieldDefinition childNodesField = new FieldDefinition();
            childNodesField.IsCompileTimeConstant = false;
            childNodesField.IsNotSerialized = false;
            childNodesField.IsReadOnly = false;
            childNodesField.IsRuntimeSpecial = false;
            childNodesField.IsSpecialName = false;
            // create array of node interface type
            VectorTypeReference nodeInterfaceArrayType = new VectorTypeReference();
            nodeInterfaceArrayType.ElementType = this.nodeInterface;
            nodeInterfaceArrayType.Rank = 1;
            nodeInterfaceArrayType.IsFrozen = true;
            nodeInterfaceArrayType.IsValueType = false;
            nodeInterfaceArrayType.InternFactory = host.InternFactory;
            childNodesField.Type = nodeInterfaceArrayType;

            childNodesField.IsStatic = false;
            childNodesField.Visibility = TypeMemberVisibility.Public;
            childNodesField.Name = host.NameTable.GetNameFor("childNodes");
            childNodesField.InternFactory = host.InternFactory;
            childNodesField.ContainingTypeDefinition = givenClass;
            givenClass.Fields.Add(childNodesField);

            // create getter for the childNodes variable
            parameters = new List<IParameterDefinition>();
            // int parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.host.PlatformType.SystemInt32;
            parameters.Add(parameter);
            MethodDefinition childNodesGetMethod = this.helperClass.createNewMethod("childNodes_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ilGenerator = new ILGenerator(host, childNodesGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, childNodesField);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Ldelem_Ref);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, childNodesGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            childNodesGetMethod.Body = body;

            // create setter for the childNodes variable
            parameters = new List<IParameterDefinition>();
            // iNode parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            // int parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.host.PlatformType.SystemInt32;
            parameters.Add(parameter);
            MethodDefinition childNodesSetMethod = this.helperClass.createNewMethod("childNodes_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, childNodesSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, childNodesField);
            ilGenerator.Emit(OperationCode.Ldarg_2);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stelem_Ref);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, childNodesSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            childNodesSetMethod.Body = body;

            // add current node field
            FieldDefinition currentNodeField = new FieldDefinition();
            currentNodeField.IsCompileTimeConstant = false;
            currentNodeField.IsNotSerialized = false;
            currentNodeField.IsReadOnly = false;
            currentNodeField.IsRuntimeSpecial = false;
            currentNodeField.IsSpecialName = false;
            currentNodeField.Type = this.nodeInterface;
            currentNodeField.IsStatic = false;
            currentNodeField.Visibility = TypeMemberVisibility.Public;
            currentNodeField.Name = host.NameTable.GetNameFor("currentNode");
            currentNodeField.InternFactory = host.InternFactory;
            currentNodeField.ContainingTypeDefinition = givenClass;
            givenClass.Fields.Add(currentNodeField);

            // create getter for the currentNode variable
            MethodDefinition currentNodeGetMethod = this.helperClass.createNewMethod("currentNode_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ilGenerator = new ILGenerator(host, currentNodeGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, currentNodeField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, currentNodeGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            currentNodeGetMethod.Body = body;

            // create setter for the currentNode variable
            parameters = new List<IParameterDefinition>();
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Name = host.NameTable.GetNameFor("value");
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            MethodDefinition currentNodeSetMethod = this.helperClass.createNewMethod("currentNode_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, currentNodeSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stfld, currentNodeField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, currentNodeSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            currentNodeSetMethod.Body = body;

            // check if debugging is activated
            // => add graph debugging attributes and methods
            MethodDefinition objectIdGetMethod = null;
            FieldDefinition objectIdField = null;
            if (this.debugging) {

                this.logger.writeLine("Debugging activated: Adding field for unique object id and getter method");

                // add objectId field
                objectIdField = new FieldDefinition();
                objectIdField.IsCompileTimeConstant = false;
                objectIdField.IsNotSerialized = false;
                objectIdField.IsReadOnly = false;
                objectIdField.IsRuntimeSpecial = false;
                objectIdField.IsSpecialName = false;
                objectIdField.Type = this.host.PlatformType.SystemString;
                objectIdField.IsStatic = false;
                objectIdField.Name = host.NameTable.GetNameFor("DEBUG_objectId");
                objectIdField.Visibility = TypeMemberVisibility.Public;
                objectIdField.InternFactory = host.InternFactory;
                objectIdField.ContainingTypeDefinition = givenClass;
                givenClass.Fields.Add(objectIdField);

                // create getter for the objectId variable
                objectIdGetMethod = this.helperClass.createNewMethod("DEBUG_objectId_get", givenClass, this.host.PlatformType.SystemString, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

                // create a body for the getter method
                ilGenerator = new ILGenerator(host, objectIdGetMethod);
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Ldfld, objectIdField);
                ilGenerator.Emit(OperationCode.Ret);
                body = new ILGeneratorMethodBody(ilGenerator, true, 1, objectIdGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
                objectIdGetMethod.Body = body;

            }

            // add .ctor(iNode) to target class
            parameters = new List<IParameterDefinition>();
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);

            MethodDefinition nodeConstructor = this.helperClass.createNewMethod(".ctor", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, false);
            nodeConstructor.IsSpecialName = true;
            nodeConstructor.IsHiddenBySignature = true;
            nodeConstructor.IsRuntimeSpecial = true;

            // generate node constructor body
            ilGenerator = new ILGenerator(host, currentNodeSetMethod);

            // create local variable list
            List<ILocalDefinition> localVariables = new List<ILocalDefinition>();

            // call system.object constructor
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Call, this.helperClass.objectCtor);

            // initialize childNodes array
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldc_I4, this.graphDimension);
            ilGenerator.Emit(OperationCode.Newarr, nodeInterfaceArrayType);
            ilGenerator.Emit(OperationCode.Stfld, childNodesField);

            // check if debugging is activated
            // => add code to constructor that generates a unique id for this object
            if (this.debugging) {

                this.logger.writeLine("Debugging activated: Adding code to generate unique id to node constructor");

                // create local integer variable needed for debugging code
                LocalDefinition intLocal = new LocalDefinition();
                intLocal.IsReference = false;
                intLocal.IsPinned = false;
                intLocal.IsModified = false;
                intLocal.Type = this.host.PlatformType.SystemInt32;
                intLocal.MethodDefinition = nodeConstructor;
                localVariables.Add(intLocal);

                // use the hash code of this instance as unique object id
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.objectGetHashCode);
                ilGenerator.Emit(OperationCode.Stloc, intLocal);

                // cast random integer to string and store in object id
                ilGenerator.Emit(OperationCode.Ldloca, intLocal);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.int32ToString);
                ilGenerator.Emit(OperationCode.Stfld, objectIdField);

            }

            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 8, nodeConstructor, localVariables, Enumerable<ITypeDefinition>.Empty);
            nodeConstructor.Body = body;


            // add class to the list of possible nodes for the graph
            PossibleNode tempStruct = new PossibleNode();
            tempStruct.nodeConstructor = nodeConstructor;
            tempStruct.givenClass = givenClass;

            // for each interface the class implements add it to the according list
            foreach (ITypeReference interfaceRef in givenClass.Interfaces) {

                this.logger.writeLine("Add class \"" + givenClass.ToString() + "\" to graph interface list \"" + interfaceRef.ToString() + "\"");

                // check if a list with this interface already exists
                // => if it does just add current class to list
                if (this.graphInterfaces.ContainsKey(interfaceRef)) {
                    List<PossibleNode> tempList = (List<PossibleNode>)this.graphInterfaces[interfaceRef];
                    tempList.Add(tempStruct);
                }
                // if not => add new list for this interface
                else {
                    List<PossibleNode> tempList = new List<PossibleNode>();
                    tempList.Add(tempStruct);
                    this.graphInterfaces.Add(interfaceRef, tempList);
                }
            }

            this.logger.writeLine("");

        }