public function getSoapTypes()
    {
        if (null === $this->types) {

            $soapTypes = $this->__getTypes();
            foreach ($soapTypes as $soapType) {
                $properties = array();
                $lines = explode("\n", $soapType);
                if (!preg_match('/struct (.*) {/', $lines[0], $matches)) {
                    continue;
                }
                $typeName = $matches[1];

                foreach (array_slice($lines, 1) as $line) {
                    if ($line == '}') {
                        continue;
                    }
                    preg_match('/\s* (.*) (.*);/', $line, $matches);
                    $properties[$matches[2]] = $matches[1];
                }

                // Since every object extends sObject, need to append sObject elements to all native and custom objects
                if ($typeName !== 'sObject' && array_key_exists('sObject', $this->types)) {
                    $properties = array_merge($properties, $this->types['sObject']);
                }

                $this->types[$typeName] = $properties;
            }
        }

        return $this->types;
    }