public override bool Rewrite(
            CodeDescriptor decompilee,
            MethodBase callee,
            StackElement[] args,
            IDecompiler stack,
            IFunctionBuilder builder)
        {
            if (args.Length < 2)
                throw new InvalidOperationException("The attribute SignalIndexer was applied to the wrong method");

            LiteralReference refExpr = args[0].Expr as LiteralReference;
            if (refExpr == null)
                throw new InvalidOperationException("Unable to resolve port/signal reference expression");

            DimSpec[] dimSamples = new DimSpec[args.Length - 1];
            Expression[] indices = args.Skip(1).Select(arg => arg.Expr).ToArray();
            bool isStatic = true;
            for (int i = 1; i < args.Length; i++)
            {
                var convidx = TypeConversions.ConvertValue(args[i].Sample, typeof(int));
                if (convidx != null)
                {
                    dimSamples[i - 1] = (int)convidx;
                }
                else if (args[i].Sample is Range)
                {
                    dimSamples[i - 1] = (Range)args[i].Sample;
                }
                else
                {
                    dimSamples = null;
                    break;
                }

                // EVariability.LocalVariable is not static as well, since variables
                // inside for loops will have that variability.
                if (args[i].Variability != EVariability.Constant)
                    isStatic = false;
            }
            IndexSpec indexSpec = null;
            indexSpec = new IndexSpec(dimSamples);

            SignalRef sigRef = null;
            LambdaLiteralVisitor llv = new LambdaLiteralVisitor()
            {
                OnVisitConstant = x =>
                {
                    sigRef = new SignalRef(
                        ((SignalBase)x.ConstantValue).Descriptor,
                        SignalRef.EReferencedProperty.Instance,
                        new Expression[][] { indices }, indexSpec, isStatic);
                },
                OnVisitFieldRef = x => { throw new InvalidOperationException(); },
                OnVisitSignalRef = x =>
                {
                    sigRef = new SignalRef(
                        x.Desc,
                        x.Prop,
                        x.Indices.Concat(new Expression[][] { indices }),
                        indexSpec.Project(x.IndexSample),
                        x.IsStaticIndex && isStatic);
                },
                OnVisitVariable = x => { throw new InvalidOperationException(); },
                OnVisitThisRef = x => { throw new InvalidOperationException(); }
            };
            refExpr.ReferencedObject.Accept(llv);

            object rsample = null;

            Type[] argTypes = args
                .Skip(1)
                .Select(a => a.Expr.ResultType.CILType)
                .ToArray();
            object[] argSamples = args
                .Select(a => a.Sample)
                .ToArray();
            MethodInfo indexerSampleMethod = callee.DeclaringType.GetMethod(
                "GetIndexerSample",
                BindingFlags.Instance | BindingFlags.NonPublic,
                null,
                argTypes,
                null);
            if (indexerSampleMethod != null && argSamples.All(a => a != null))
            {
                rsample = indexerSampleMethod.Invoke(argSamples);
            }
            else
            {
                try
                {
                    rsample = callee.Invoke(args.Select(x => x.Sample).ToArray());
                }
                catch (TargetInvocationException)
                {
                }
            }
            stack.Push(sigRef, rsample);
            return true;
        }
        public override bool Rewrite(
            CodeDescriptor decompilee,
            MethodBase callee,
            StackElement[] args,
            IDecompiler stack,
            IFunctionBuilder builder)
        {
            if (args.Length == 0)
                throw new InvalidOperationException("The attribute SignalProperty was applied to the wrong method");

            LiteralReference refExpr = args[0].Expr as LiteralReference;
            if (refExpr == null)
                throw new InvalidOperationException("Unable to resolve port/signal reference expression");

            ISignal sigSample = args[0].Sample as ISignal;

            SignalRef sigRef = null;
            LambdaLiteralVisitor llv = new LambdaLiteralVisitor()
            {
                OnVisitConstant = x =>
                {
                    sigRef = ((ISignal)x.ConstantValue).ToSignalRef(Prop);
                },
                OnVisitSignalRef = x =>
                {
                    sigRef = new SignalRef(x.Desc, Prop, x.Indices, x.IndexSample, x.IsStaticIndex);
                },
                OnVisitVariable = x =>
                {
                    SignalArgumentDescriptor desc = decompilee.GetSignalArguments().Where(y => y.Name.Equals(x.Name)).Single();
                    sigRef = new SignalRef(desc, Prop);
                },
                OnVisitFieldRef = x =>
                {
                    sigRef = ((ISignal)x.FieldDesc.ConstantValue).ToSignalRef(Prop);
                },
                OnVisitThisRef = x => { throw new InvalidOperationException(); },
                OnVisitArrayRef = x => { throw new InvalidOperationException(); }
            };
            refExpr.ReferencedObject.Accept(llv);

            ParameterInfo[] pis = callee.GetParameters();
            switch (Prop)
            {
                case SignalRef.EReferencedProperty.ChangedEvent:
                case SignalRef.EReferencedProperty.Cur:
                case SignalRef.EReferencedProperty.FallingEdge:
                case SignalRef.EReferencedProperty.Pre:
                case SignalRef.EReferencedProperty.RisingEdge:
                    //if (pis.Length != 0 || callee.IsStatic)
                    //    throw new InvalidOperationException("The attribute SignalProperty was applied to the wrong method.");

                    switch (Prop)
                    {
                        case SignalRef.EReferencedProperty.Cur:
                        case SignalRef.EReferencedProperty.Pre:
                            stack.Push(
                                sigRef,
                                sigSample != null ? sigSample.InitialValueObject : null);
                            break;

                        case SignalRef.EReferencedProperty.ChangedEvent:
                            stack.Push(
                                sigRef,
                                null);
                            break;

                        case SignalRef.EReferencedProperty.FallingEdge:
                        case SignalRef.EReferencedProperty.RisingEdge:
                            stack.Push(
                                sigRef,
                                false);
                            break;

                        default:
                            throw new NotImplementedException();
                    }
                    break;

                case SignalRef.EReferencedProperty.Next:
                    if (pis.Length != 1 || callee.IsStatic)
                        throw new InvalidOperationException("The attribute SignalProperty was applied to the wrong method.");

                    builder.Store(sigRef, args[1].Expr);
                    decompilee.AddDrivenSignal(sigRef.Desc);
                    break;

                default:
                    throw new NotImplementedException();
            }
            return true;
        }