SLBaseExpr MarshalProtocolListTypeSpec(BaseDeclaration declContext, string name, ProtocolListTypeSpec protocols)
        {
            // let p = UnsafeMutablePointer<protoType>.allocate (argName)
            // p.initialize(to: argName)
            // exp is toIntPtr(value: p)
            // ...
            // if isInOut:
            // argName = p.pointee
            // always:
            // p.deinitialize ()
            // p.deallocate ()
            var bindingName = new SLIdentifier(MarshalEngine.Uniqueify(name, identifiersUsed));
            var argType     = typeMapper.TypeSpecMapper.MapType(declContext, imports, protocols, false);
            var ptrType     = new SLBoundGenericType("UnsafeMutablePointer", argType);

            identifiersUsed.Add(bindingName.Name);
            var decl = new SLDeclaration(true, bindingName, ptrType,
                                         new SLFunctionCall(ptrType + ".allocate", false, new SLArgument(new SLIdentifier("capacity"), SLConstant.Val(1), true)),
                                         Visibility.None, false);
            var varBinding = new SLLine(decl);

            preMarshalCode.Add(varBinding);
            var initCall = SLFunctionCall.FunctionCallLine(bindingName.Name + ".initialize",
                                                           new SLArgument(new SLIdentifier("to"), new SLIdentifier(name), true));

            preMarshalCode.Add(initCall);
            imports.AddIfNotPresent("XamGlue");
            if (protocols.IsInOut)
            {
                postMarshalCode.Add(new SLLine(new SLBinding(name, bindingName.Dot(new SLIdentifier("pointee")))));
            }
            postMarshalCode.Add(SLFunctionCall.FunctionCallLine($"{bindingName.Name}.deinitialize", new SLArgument(new SLIdentifier("count"), SLConstant.Val(1), true)));
            postMarshalCode.Add(SLFunctionCall.FunctionCallLine($"{bindingName.Name}.deallocate"));
            return(new SLFunctionCall("toIntPtr", false, new SLArgument(new SLIdentifier("value"), bindingName, true)));
        }
        SLBaseExpr MarshalTupleTypeSpec(BaseDeclaration declContext, string name, TupleTypeSpec tuple)
        {
            var bindingName = new SLIdentifier(MarshalEngine.Uniqueify(name, identifiersUsed));
            var argType     = typeMapper.TypeSpecMapper.MapType(declContext, imports, tuple, false);
            var ptrType     = new SLBoundGenericType("UnsafeMutablePointer", argType);

            identifiersUsed.Add(bindingName.Name);
            var decl = new SLDeclaration(true, bindingName, ptrType,
                                         new SLFunctionCall(ptrType + ".allocate", false, new SLArgument(new SLIdentifier("capacity"), SLConstant.Val(1), true)),
                                         Visibility.None, false);
            var varBinding = new SLLine(decl);

            preMarshalCode.Add(varBinding);
            var initCall = SLFunctionCall.FunctionCallLine(bindingName.Name + ".initialize",
                                                           new SLArgument(new SLIdentifier("to"), new SLIdentifier(name), true));

            preMarshalCode.Add(initCall);
            imports.AddIfNotPresent("XamGlue");
            if (tuple.IsInOut)
            {
                postMarshalCode.Add(new SLLine(new SLBinding(name, bindingName.Dot(new SLIdentifier("pointee")))));
            }
            return(new SLFunctionCall("toIntPtr", false, new SLArgument(new SLIdentifier("value"), bindingName, true)));
        }