internal static bool AreEquivalent(Instruction source, Instruction target)
        {
            if (source.OpCode.Code != target.OpCode.Code)
                return false;

            if (source.OpCode.Code == Code.Ldstr)
                return true;

            //Check the types in ldarg stuff.  Sometimes this scheme
            //could lead us to false positives.  We need an analysis
            //which depends on the context.
            if (source.IsLoadArgument ()) {
                // case where 'ldarg this' is used (p.GetSequence () would be 0)
                if (!Current.HasParameters && !Target.HasParameters)
                    return true;
                return AreEquivalent (source.GetParameter (Current), target.GetParameter (Target));
            }

            // The same for ldloc / stloc
            if (source.IsLoadLocal () || source.IsStoreLocal ())
                return AreEquivalent (source.GetVariable (Current), target.GetVariable (Target));

            //WARNING: Dirty Evil Hack: this should be in the
            //Pattern class
            if (source.OpCode.Code == Code.Ret && source.Previous != null &&
                (source.Previous.OpCode.StackBehaviourPush == StackBehaviour.Pushi ||
                source.Previous.OpCode.Code == Code.Ldnull ||
                source.Previous.OpCode.StackBehaviourPush == StackBehaviour.Push1))
                return false;

            //if (source.Operand != target.Operand)
            if (source.Operand != null && target.Operand != null) {
                // we're sure that target.Operand is of the same type as source.Operand (same OpCode is used)
                Instruction si = (source.Operand as Instruction);
                if (si != null)
                    return (si.Offset == ((Instruction) target.Operand).Offset);
                IMetadataTokenProvider sm = (source.Operand as IMetadataTokenProvider);
                if (sm != null)
                    return sm.Equals (target.Operand as IMetadataTokenProvider);
                if (source.Operand == target.Operand)
                    return true;
                // last chance: we do call ToString
                if (source.Operand.ToString () != target.Operand.ToString ())
                    return false;
            }

            return true;
        }
		static bool OriginsMatch (MethodDefinition method, Instruction lhs, Instruction rhs)
		{
			bool match = false;

			object operand1 = lhs.GetOperand (method);
			object operand2 = rhs.GetOperand (method);

			if (lhs.OpCode.Code == rhs.OpCode.Code) {
				if (lhs.IsLoadArgument ())
					match = operand1.Equals (operand2);

				else if (lhs.IsLoadElement ())
					match = LoadElementMatch (method, lhs, rhs);

				else if (lhs.IsLoadIndirect ())
					match = LoadIndirectMatch (method, lhs, rhs);

				else if (lhs.IsLoadLocal ())
					match = LocalsMatch (operand1, operand2);

			} else if (lhs.IsStoreLocal () && rhs.IsLoadLocal ())
				match = LocalsMatch (operand1, operand2);

			else if (lhs.IsLoadLocal () && rhs.IsStoreLocal ())
				match = LocalsMatch (operand1, operand2);

			return match;
		}